<!DOCTYPE html>
<html ng-app="demoApp">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>组件演示 - ng-components-ui</title>
    <link
      rel="stylesheet"
      href="https://cdn.jsdelivr.net/npm/bootstrap@3.4.1/dist/css/bootstrap.min.css"
    />
    <link rel="stylesheet" href="../dist/ng-components.css" />
    <link rel="stylesheet" href="../lib/kindeditor/themes/default/default.css" />
    <style>
      * {
        box-sizing: border-box;
      }

      body {
        font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto,
          "Helvetica Neue", Arial, sans-serif;
        margin: 0;
        padding: 0;
        background: #f5f5f5;
      }

      .header {
        background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
        color: white;
        padding: 30px 40px;
        box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);
      }

      .header h1 {
        margin: 0 0 10px 0;
        font-size: 32px;
      }

      .header p {
        margin: 0;
        opacity: 0.9;
        font-size: 16px;
      }

      .nav-tabs {
        background: white;
        border-bottom: 2px solid #e0e0e0;
        padding: 0 40px;
        display: flex;
        gap: 5px;
        box-shadow: 0 2px 4px rgba(0, 0, 0, 0.05);
      }

      .nav-tab {
        padding: 15px 25px;
        cursor: pointer;
        border: none;
        background: transparent;
        color: #666;
        font-size: 15px;
        font-weight: 500;
        border-bottom: 3px solid transparent;
        transition: all 0.2s;
      }

      .nav-tab:hover {
        color: #667eea;
        background: #f5f5f5;
      }

      .nav-tab.active {
        color: #667eea;
        border-bottom-color: #667eea;
      }

      .container {
        max-width: 1400px;
        margin: 0 auto;
        padding: 40px;
      }

      .tab-content {
        display: none;
      }

      .tab-content.active {
        display: block;
        animation: fadeIn 0.3s;
      }

      @keyframes fadeIn {
        from {
          opacity: 0;
          transform: translateY(10px);
        }
        to {
          opacity: 1;
          transform: translateY(0);
        }
      }

      .demo-section {
        background: white;
        padding: 30px;
        border-radius: 8px;
        box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);
        margin-bottom: 30px;
      }

      .demo-section h2 {
        margin: 0 0 20px 0;
        color: #333;
        font-size: 20px;
        border-bottom: 2px solid #667eea;
        padding-bottom: 10px;
      }

      .demo-section h3 {
        margin: 20px 0 15px 0;
        color: #555;
        font-size: 16px;
        font-weight: 600;
      }

      .demo-section p {
        color: #666;
        line-height: 1.6;
        margin: 0 0 15px 0;
      }

      .demo-actions {
        display: flex;
        gap: 15px;
        flex-wrap: wrap;
        margin: 20px 0;
      }

      .btn {
        padding: 10px 20px;
        border: none;
        border-radius: 6px;
        cursor: pointer;
        font-size: 14px;
        font-weight: 500;
        transition: all 0.2s;
        box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
      }

      .btn:hover {
        transform: translateY(-2px);
        box-shadow: 0 4px 8px rgba(0, 0, 0, 0.15);
      }

      .btn:active {
        transform: translateY(0);
      }

      .btn-primary {
        background: #667eea;
        color: white;
      }

      .btn-primary:hover {
        background: #5568d3;
      }

      .btn-success {
        background: #48bb78;
        color: white;
      }

      .btn-success:hover {
        background: #38a169;
      }

      .btn-warning {
        background: #ed8936;
        color: white;
      }

      .btn-warning:hover {
        background: #dd6b20;
      }

      .btn-danger {
        background: #f56565;
        color: white;
      }

      .btn-danger:hover {
        background: #e53e3e;
      }

      .btn-info {
        background: #4299e1;
        color: white;
      }

      .btn-info:hover {
        background: #3182ce;
      }

      .debug-output {
        background: #2d3748;
        color: #e2e8f0;
        padding: 20px;
        border-radius: 6px;
        margin-top: 20px;
        font-family: "Monaco", "Menlo", "Ubuntu Mono", monospace;
        font-size: 13px;
      }

      .debug-output strong {
        color: #90cdf4;
        display: block;
        margin-bottom: 10px;
      }

      .debug-output pre {
        margin: 0;
        white-space: pre-wrap;
        word-wrap: break-word;
      }

      .tree-demo-grid {
        display: grid;
        grid-template-columns: repeat(auto-fit, minmax(450px, 1fr));
        gap: 30px;
        margin-top: 20px;
      }

      .tree-demo-item {
        border: 1px solid #e0e0e0;
        border-radius: 6px;
        padding: 20px;
        background: #fafafa;
      }

      .tree-demo-item h3 {
        margin: 0 0 15px 0;
        color: #667eea;
        font-size: 15px;
      }

      .select-demo-grid {
        display: grid;
        grid-template-columns: repeat(auto-fit, minmax(320px, 1fr));
        gap: 30px;
        margin-top: 20px;
      }

      .select-demo-item {
        border: 1px solid #e0e0e0;
        border-radius: 6px;
        padding: 20px;
        background: #fafafa;
      }

      .select-demo-item h3 {
        margin: 0 0 15px 0;
        color: #667eea;
        font-size: 15px;
      }

      .select-demo-item p {
        color: #666;
        margin: 0 0 15px 0;
      }

      .select-demo-item .ng-select-container {
        width: 100%;
        min-width: 0;
      }

      .date-demo-grid {
        display: grid;
        grid-template-columns: repeat(auto-fit, minmax(320px, 1fr));
        gap: 30px;
        margin-top: 20px;
      }

      .date-demo-item {
        border: 1px solid #e0e0e0;
        border-radius: 6px;
        padding: 20px;
        background: #fafafa;
      }

      .date-demo-item h3 {
        margin: 0 0 15px 0;
        color: #667eea;
        font-size: 15px;
      }

      .image-preview-grid {
        display: grid;
        grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
        gap: 24px;
        margin-top: 20px;
      }

      .image-preview-card {
        border: 1px solid #e0e0e0;
        border-radius: 8px;
        padding: 20px;
        background: #fafafa;
        display: flex;
        flex-direction: column;
        gap: 12px;
      }

      .image-preview-card h3 {
        margin: 0;
        color: #667eea;
        font-size: 16px;
      }

      .image-preview-card p {
        margin: 0;
        color: #666;
        font-size: 14px;
        line-height: 1.5;
      }

      .image-preview-card img {
        width: 100%;
        border-radius: 8px;
        display: block;
        box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
      }

      .tinymce-demo-grid {
        display: flex;
        flex-direction: column;
        gap: 24px;
        margin-top: 20px;
        width: 100%;
      }

      .tinymce-demo-item {
        border: 1px solid #e0e0e0;
        border-radius: 8px;
        padding: 20px;
        background: #fafafa;
        display: flex;
        flex-direction: column;
        gap: 16px;
      }

      .tinymce-demo-item h3 {
        margin: 0;
        color: #667eea;
        font-size: 16px;
      }

      .tinymce-status {
        padding: 10px 14px;
        border-radius: 6px;
        background: #edf2ff;
        color: #3b5bdb;
        font-size: 13px;
      }

      .tinymce-guide {
        background: #f7fafc;
        border-left: 4px solid #667eea;
        padding: 12px 16px;
        border-radius: 6px;
        font-size: 13px;
        color: #4a5568;
      }

      .tinymce-guide ul {
        margin: 8px 0 0 16px;
        padding: 0;
      }

      .tinymce-guide li {
        margin-bottom: 6px;
        line-height: 1.4;
      }

      .image-preview-controls {
        display: flex;
        align-items: center;
        gap: 12px;
      }

      .toast-demo-actions {
        display: flex;
        flex-wrap: wrap;
        gap: 10px;
        margin: 20px 0;
      }

      .toast-demo-actions .btn {
        flex: 1 1 180px;
      }

      .strap-demo {
        display: flex;
        gap: 24px;
      }

      .strap-nav {
        flex: 0 0 240px;
      }

      .strap-nav .nav {
        position: relative;
      }

      .strap-nav .nav > li > a {
        padding: 10px 14px;
        border-radius: 6px;
        color: #4a5568;
        transition: all 0.2s ease;
      }

      .strap-nav .nav > li.active > a,
      .strap-nav .nav > li > a:hover {
        background: #667eea;
        color: #fff;
      }

      .strap-content {
        flex: 1;
        min-width: 0;
      }

      .strap-section + .strap-section {
        margin-top: 30px;
      }

      .strap-example {
        background: #f9fafc;
        border: 1px solid #e2e8f0;
        padding: 16px;
        border-radius: 6px;
        margin-bottom: 15px;
      }

      .strap-example .btn {
        margin-right: 10px;
        margin-bottom: 10px;
      }

      .strap-inline {
        display: flex;
        flex-wrap: wrap;
        gap: 20px;
        align-items: center;
      }

      .strap-form-control {
        max-width: 260px;
      }

      @media (max-width: 992px) {
        .strap-demo {
          flex-direction: column;
        }

        .strap-nav {
          flex: none;
        }

        .strap-nav .nav {
          display: flex;
          overflow-x: auto;
          gap: 10px;
        }

        .strap-nav .nav > li > a {
          white-space: nowrap;
        }
      }

      .tree-container {
        background: white;
        border: 1px solid #e0e0e0;
        border-radius: 4px;
        padding: 15px;
        margin-bottom: 15px;
        max-height: 400px;
        overflow-y: auto;
      }

      .code-block {
        background: #f7fafc;
        border: 1px solid #e2e8f0;
        border-radius: 4px;
        padding: 15px;
        margin: 10px 0;
        font-family: "Monaco", "Menlo", "Ubuntu Mono", monospace;
        font-size: 12px;
        overflow-x: auto;
      }

      .code-block code {
        color: #2d3748;
      }

      .feature-list {
        background: #f7fafc;
        border-left: 4px solid #667eea;
        padding: 15px 20px;
        margin: 20px 0;
      }

      .feature-list ul {
        margin: 0;
        padding-left: 20px;
      }

      .feature-list li {
        color: #4a5568;
        margin: 8px 0;
        line-height: 1.6;
      }

      .standalone-link {
        display: inline-block;
        margin-bottom: 20px;
        padding: 10px 20px;
        background: #667eea;
        color: white;
        text-decoration: none;
        border-radius: 6px;
        font-size: 14px;
        font-weight: 500;
        transition: all 0.2s;
        box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
      }

      .standalone-link:hover {
        background: #5568d3;
        transform: translateY(-2px);
        box-shadow: 0 4px 8px rgba(0, 0, 0, 0.15);
      }

      .standalone-link::after {
        content: " →";
        margin-left: 5px;
      }
    </style>
  </head>
  <body ng-controller="DemoController">
    <div class="header">
      <h1>ng-components-ui 组件库</h1>
      <p>基于 AngularJS 1.x 的通用组件库</p>
    </div>

    <ng-toast-container placement="top-right"></ng-toast-container>

    <div class="nav-tabs">
      <button
        class="nav-tab"
        ng-class="{active: activeTab === 'confirm'}"
        ng-click="setActiveTab('confirm')"
      >
        确认对话框
      </button>
      <button
        class="nav-tab"
        ng-class="{active: activeTab === 'tree'}"
        ng-click="setActiveTab('tree')"
      >
        多级树选择
      </button>
      <button
        class="nav-tab"
        ng-class="{active: activeTab === 'treeSelect'}"
        ng-click="setActiveTab('treeSelect')"
      >
        下拉树选择
      </button>
      <button
        class="nav-tab"
        ng-class="{active: activeTab === 'select'}"
        ng-click="setActiveTab('select')"
      >
        下拉选择
      </button>
      <button
        class="nav-tab"
        ng-class="{active: activeTab === 'datePicker'}"
        ng-click="setActiveTab('datePicker')"
      >
        日期选择
      </button>
      <button
        class="nav-tab"
        ng-class="{active: activeTab === 'imagePreview'}"
        ng-click="setActiveTab('imagePreview')"
      >
        图片预览
      </button>
      <button
        class="nav-tab"
        ng-class="{active: activeTab === 'toast'}"
        ng-click="setActiveTab('toast')"
      >
        通知提示
      </button>
      <button
        class="nav-tab"
        ng-class="{active: activeTab === 'strap'}"
        ng-click="setActiveTab('strap')"
      >
        Angular-Strap
      </button>
      <button
        class="nav-tab"
        ng-class="{active: activeTab === 'radio'}"
        ng-click="setActiveTab('radio')"
      >
        单选框
      </button>
      <button
        class="nav-tab"
        ng-class="{active: activeTab === 'resize'}"
        ng-click="setActiveTab('resize')"
      >
        大小缩放
      </button>
      <button
        class="nav-tab"
        ng-class="{active: activeTab === 'loading'}"
        ng-click="setActiveTab('loading')"
      >
        加载动画
      </button>
      <button
        class="nav-tab"
        ng-class="{active: activeTab === 'tinymce'}"
        ng-click="setActiveTab('tinymce')"
      >
        TinyMCE 富文本
      </button>
      <button
        class="nav-tab"
        ng-class="{active: activeTab === 'kindeditor'}"
        ng-click="setActiveTab('kindeditor')"
      >
        富文本编辑器
      </button>
    </div>

    <div class="container">
      <!-- Confirm Dialog Demo -->
      <div class="tab-content" ng-class="{active: activeTab === 'confirm'}">
        <div class="demo-section">
          <a href="confirm.html" class="standalone-link">查看独立演示页</a>

          <h2>确认对话框组件</h2>

          <div class="feature-list">
            <strong>功能特性:</strong>
            <ul>
              <li>支持多种对话框类型（信息、成功、警告、危险）</li>
              <li>自定义标题和内容</li>
              <li>可配置按钮文本和回调</li>
              <li>支持HTML内容</li>
              <li>优雅的动画效果</li>
            </ul>
          </div>

          <h3>使用示例</h3>
          <div class="demo-actions">
            <button class="btn btn-primary" ng-click="showInfo()">
              信息对话框
            </button>
            <button class="btn btn-success" ng-click="showSuccess()">
              成功对话框
            </button>
            <button class="btn btn-warning" ng-click="showWarning()">
              警告对话框
            </button>
            <button class="btn btn-danger" ng-click="showDanger()">
              危险对话框
            </button>
            <button class="btn btn-info" ng-click="showCustom()">
              自定义对话框
            </button>
          </div>

          <div class="code-block">
            <code>
// 基本用法<br>
$confirm.show({<br>
&nbsp;&nbsp;title: '确认操作',<br>
&nbsp;&nbsp;content: '您确定要执行此操作吗？',<br>
&nbsp;&nbsp;type: 'warning',<br>
&nbsp;&nbsp;okText: '确定',<br>
&nbsp;&nbsp;cancelText: '取消'<br>
}).then(function() {<br>
&nbsp;&nbsp;// 用户点击确定<br>
}, function() {<br>
&nbsp;&nbsp;// 用户点击取消<br>
});
            </code>
          </div>
        </div>
      </div>

      <!-- Multi-Level Tree Demo -->
      <div class="tab-content" ng-class="{active: activeTab === 'tree'}">
        <div class="demo-section">
          <a href="tree.html" class="standalone-link">查看独立演示页</a>

          <h2>多级树选择组件</h2>

          <div class="feature-list">
            <strong>功能特性:</strong>
            <ul>
              <li>支持无限层级的树形结构</li>
              <li>单选/多选模式</li>
              <li>级联选择（选中父节点自动选中所有子节点）</li>
              <li>父节点简化模式（选中所有子节点时只返回父节点ID）</li>
              <li>半选状态显示</li>
              <li>自定义ID和标签字段</li>
              <li>流畅的展开/折叠动画</li>
            </ul>
          </div>

          <div class="tree-demo-grid">
            <!-- Demo 1: 基本多选 + 级联 + 搜索 -->
            <div class="tree-demo-item">
              <h3>1. 基本多选 + 级联 + 搜索 🔍</h3>
              <p>选中父节点会自动选中所有子节点，支持搜索功能</p>
              <div class="tree-container">
                <multi-level-tree
                  tree-data="treeData1"
                  id="BpaId"
                  label="cnName"
                  cascade="true"
                  multiple="true"
                  searchable="true"
                  search-placeholder="搜索节点..."
                  ng-model="selectedIds1_1"
                >
                </multi-level-tree>
              </div>
              <div class="debug-output">
                <strong>选中的节点:</strong>
                <pre>{{ selectedIds1_1 | json }}</pre>
              </div>
            </div>

            <!-- Demo 2: 单选模式 -->
            <div class="tree-demo-item">
              <h3>2. 单选模式</h3>
              <p>每次只能选中一个节点</p>
              <div class="tree-container">
                <multi-level-tree
                  tree-data="treeData1"
                  id="BpaId"
                  label="cnName"
                  cascade="false"
                  multiple="false"
                  ng-model="selectedIds1_2"
                >
                </multi-level-tree>
              </div>
              <div class="debug-output">
                <strong>选中的节点:</strong>
                <pre>{{ selectedIds1_2 | json }}</pre>
              </div>
            </div>

            <!-- Demo 3: 多选但不级联 -->
            <div class="tree-demo-item">
              <h3>3. 多选但不级联</h3>
              <p>可以多选，但选中父节点不会影响子节点</p>
              <div class="tree-container">
                <multi-level-tree
                  tree-data="treeData1"
                  id="BpaId"
                  label="cnName"
                  cascade="false"
                  multiple="true"
                  ng-model="selectedIds1_3"
                >
                </multi-level-tree>
              </div>
              <div class="debug-output">
                <strong>选中的节点:</strong>
                <pre>{{ selectedIds1_3 | json }}</pre>
              </div>
            </div>

            <!-- Demo 4: 复杂组织架构 -->
            <div class="tree-demo-item">
              <h3>4. 复杂组织架构</h3>
              <p>实际业务场景中的多层级组织结构</p>
              <div class="tree-container">
                <multi-level-tree
                  tree-data="treeData2"
                  id="BpaId"
                  label="cnName"
                  cascade="true"
                  multiple="true"
                  ng-model="selectedIds1_4"
                >
                </multi-level-tree>
              </div>
              <div class="debug-output">
                <strong>选中的节点:</strong>
                <pre>{{ selectedIds1_4 | json }}</pre>
              </div>
            </div>

            <!-- Demo 5: 父节点简化模式 -->
            <div class="tree-demo-item">
              <h3>5. 父节点简化模式</h3>
              <p>选中所有子节点时只返回父节点ID（初始值示例）</p>
              <div class="tree-container">
                <multi-level-tree
                  tree-data="treeData2"
                  id="BpaId"
                  label="cnName"
                  cascade="true"
                  multiple="true"
                  cascade-return-parent-only="true"
                  ng-model="selectedIds1_5"
                >
                </multi-level-tree>
              </div>
              <div class="debug-output">
                <strong>选中的节点 (简化后):</strong>
                <pre>{{ selectedIds1_5 | json }}</pre>
              </div>
            </div>

            <!-- Demo 6: 自定义字段 -->
            <div class="tree-demo-item">
              <h3>6. 自定义ID和标签字段</h3>
              <p>使用自定义的字段名称</p>
              <div class="tree-container">
                <multi-level-tree
                  tree-data="treeData3"
                  id="id"
                  label="name"
                  cascade="true"
                  multiple="true"
                  ng-model="selectedIds1_6"
                >
                </multi-level-tree>
              </div>
              <div class="debug-output">
                <strong>选中的节点:</strong>
                <pre>{{ selectedIds1_6 | json }}</pre>
              </div>
            </div>

            <!-- Demo 7: 大型树结构 -->
            <div class="tree-demo-item" style="grid-column: 1 / -1;">
              <h3>7. 大型树结构性能测试 🚀 (带搜索功能)</h3>
              <p style="color: #e53e3e; font-weight: 600;">
                包含 <strong>{{ treeData4Stats.totalNodes }}</strong> 个节点，4层深度
                ({{ treeData4Stats.level1 }} 个一级部门 × {{ treeData4Stats.level2 }} 个中心 × {{ treeData4Stats.level3 }} 个团队 × {{ treeData4Stats.level4 }} 个员工)
              </p>
              <div style="background: #fff3cd; border-left: 4px solid #ffc107; padding: 12px; margin: 15px 0; border-radius: 4px;">
                <strong style="color: #856404;">性能测试说明:</strong>
                <ul style="margin: 8px 0 0 0; padding-left: 20px; color: #856404;">
                  <li>测试树组件在大数据量下的渲染性能</li>
                  <li>测试级联选择的性能（选中一级节点将选中所有子节点）</li>
                  <li>测试展开/折叠的流畅度</li>
                  <li>测试父节点简化功能的处理速度</li>
                  <li><strong style="color: #d32f2f;">🔍 新增：测试搜索功能（输入"张三"、"研发"、"团队"等关键词试试）</strong></li>
                </ul>
              </div>
              <div class="tree-container" style="max-height: 600px;">
                <multi-level-tree
                  tree-data="treeData4"
                  id="BpaId"
                  label="cnName"
                  cascade="true"
                  multiple="true"
                  cascade-return-parent-only="true"
                  searchable="true"
                  search-placeholder="搜索节点（尝试输入：张三、研发、团队）..."
                  ng-model="selectedIds1_7"
                >
                </multi-level-tree>
              </div>
              <div class="debug-output">
                <strong>选中的节点 (简化后):</strong>
                <pre>{{ selectedIds1_7 | json }}</pre>
                <div style="margin-top: 15px; padding: 10px; background: #1e293b; border-radius: 4px;">
                  <strong style="color: #38bdf8;">实时统计:</strong><br>
                  <span style="color: #a5f3fc;">选中节点数量: {{ selectedIds1_7.length }}</span><br>
                  <span style="color: #a5f3fc;">树节点总数: {{ treeData4Stats.totalNodes }}</span><br>
                  <span style="color: #a5f3fc;">选中率: {{ (selectedIds1_7.length / treeData4Stats.totalNodes * 100).toFixed(2) }}%</span>
                </div>
                <div style="margin-top: 10px; padding: 10px; background: #065f46; border-radius: 4px; color: #d1fae5;">
                  <strong>操作建议:</strong><br>
                  1. 尝试选中一个一级部门，观察级联选择性能<br>
                  2. 观察父节点简化功能：选中所有子节点后，返回值只包含父节点ID<br>
                  3. 逐层展开节点，测试大量DOM的渲染性能<br>
                  4. 快速切换选中状态，测试响应速度
                </div>
              </div>
            </div>
          </div>

          <div class="code-block" style="margin-top: 30px;">
            <code>
// HTML 使用方式<br>
&lt;multi-level-tree<br>
&nbsp;&nbsp;tree-data="treeData"<br>
&nbsp;&nbsp;id="BpaId"<br>
&nbsp;&nbsp;label="cnName"<br>
&nbsp;&nbsp;cascade="true"<br>
&nbsp;&nbsp;multiple="true"<br>
&nbsp;&nbsp;cascade-return-parent-only="false"<br>
&nbsp;&nbsp;ng-model="selectedIds"&gt;<br>
&lt;/multi-level-tree&gt;<br>
<br>
// Controller 中的数据结构<br>
$scope.treeData = [<br>
&nbsp;&nbsp;{<br>
&nbsp;&nbsp;&nbsp;&nbsp;BpaId: "1",<br>
&nbsp;&nbsp;&nbsp;&nbsp;cnName: "一级节点",<br>
&nbsp;&nbsp;&nbsp;&nbsp;children: [<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;BpaId: "1-1",<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;cnName: "二级节点",<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;children: []<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br>
&nbsp;&nbsp;&nbsp;&nbsp;]<br>
&nbsp;&nbsp;}<br>
];<br>
<br>
$scope.selectedIds = []; // 双向绑定的选中ID数组
            </code>
          </div>
        </div>
      </div>

      <!-- Tree Select Demo -->
      <div class="tab-content" ng-class="{active: activeTab === 'treeSelect'}">
        <div class="demo-section">
          <a href="tree-select.html" class="standalone-link">查看独立演示页</a>

          <h2>下拉树选择组件</h2>

          <div class="feature-list">
            <strong>功能特性:</strong>
            <ul>
              <li>支持单选/多选模式</li>
              <li>支持搜索过滤节点</li>
              <li>支持级联选择</li>
              <li>支持父节点简化模式</li>
              <li>支持清空功能</li>
              <li>支持禁用状态</li>
              <li>多选模式下显示已选数量统计</li>
            </ul>
          </div>

          <div class="tree-demo-grid">
            <!-- Demo 1: 单选下拉树 -->
            <div class="tree-demo-item">
              <h3>1. 单选下拉树</h3>
              <p>选中后自动关闭下拉</p>
              <tree-select
                tree-data="treeData1"
                id="BpaId"
                label="cnName"
                multiple="false"
                cascade="false"
                ng-model="selectIds1"
                placeholder="请选择节点"
                clearable="true">
              </tree-select>
              <div class="debug-output">
                <strong>选中的节点:</strong>
                <pre>{{ selectIds1 | json }}</pre>
              </div>
            </div>

            <!-- Demo 2: 多选下拉树 -->
            <div class="tree-demo-item">
              <h3>2. 多选下拉树</h3>
              <p>支持多选,显示"已选 N 项"</p>
              <tree-select
                tree-data="treeData1"
                id="BpaId"
                label="cnName"
                multiple="true"
                cascade="false"
                ng-model="selectIds2"
                placeholder="请选择节点"
                clearable="true">
              </tree-select>
              <div class="debug-output">
                <strong>选中的节点:</strong>
                <pre>{{ selectIds2 | json }}</pre>
              </div>
            </div>

            <!-- Demo 3: 多选 + 级联 -->
            <div class="tree-demo-item">
              <h3>3. 多选 + 级联</h3>
              <p>选中父节点自动选中所有子节点</p>
              <tree-select
                tree-data="treeData2"
                id="BpaId"
                label="cnName"
                multiple="true"
                cascade="true"
                ng-model="selectIds3"
                placeholder="请选择部门"
                clearable="true">
              </tree-select>
              <div class="debug-output">
                <strong>选中的节点:</strong>
                <pre>{{ selectIds3 | json }}</pre>
              </div>
            </div>

            <!-- Demo 4: 级联 + 父节点简化 -->
            <div class="tree-demo-item">
              <h3>4. 级联 + 父节点简化</h3>
              <p>选中所有子节点时只返回父节点ID</p>
              <tree-select
                tree-data="treeData2"
                id="BpaId"
                label="cnName"
                multiple="true"
                cascade="true"
                cascade-return-parent-only="true"
                ng-model="selectIds4"
                placeholder="请选择部门"
                clearable="true">
              </tree-select>
              <div class="debug-output">
                <strong>选中的节点 (简化后):</strong>
                <pre>{{ selectIds4 | json }}</pre>
              </div>
            </div>

            <!-- Demo 5: 禁用状态 -->
            <div class="tree-demo-item">
              <h3>5. 禁用状态</h3>
              <p>禁用整个选择器</p>
              <tree-select
                tree-data="treeData1"
                id="BpaId"
                label="cnName"
                multiple="true"
                cascade="true"
                ng-model="selectIds5"
                placeholder="已禁用"
                disabled="true"
                clearable="true">
              </tree-select>
              <div class="debug-output">
                <strong>选中的节点:</strong>
                <pre>{{ selectIds5 | json }}</pre>
              </div>
            </div>

            <!-- Demo 6: 带初始值 -->
            <div class="tree-demo-item">
              <h3>6. 带初始值</h3>
              <p>组件加载时显示预设的选中值</p>
              <tree-select
                tree-data="treeData2"
                id="BpaId"
                label="cnName"
                multiple="true"
                cascade="true"
                ng-model="selectIds6"
                placeholder="请选择部门"
                clearable="true">
              </tree-select>
              <div class="debug-output">
                <strong>选中的节点:</strong>
                <pre>{{ selectIds6 | json }}</pre>
              </div>
            </div>

            <!-- Demo 7: 不级联多选 -->
            <div class="tree-demo-item">
              <h3>7. 不级联多选</h3>
              <p>多选模式，不级联子节点</p>
              <tree-select
                tree-data="treeData1"
                id="BpaId"
                label="cnName"
                multiple="true"
                cascade="false"
                ng-model="selectIds7"
                placeholder="请选择节点"
                clearable="true">
              </tree-select>
              <div class="debug-output">
                <strong>选中的节点:</strong>
                <pre>{{ selectIds7 | json }}</pre>
              </div>
            </div>

            <!-- Demo 8: 综合测试 - 初始值+级联+简化 -->
            <div class="tree-demo-item">
              <h3>8. 综合测试 🔥</h3>
              <p>初始值 + 级联 + 父节点简化</p>
              <tree-select
                tree-data="treeData2"
                id="BpaId"
                label="cnName"
                multiple="true"
                cascade="true"
                cascade-return-parent-only="true"
                ng-model="selectIds8"
                placeholder="请选择部门"
                clearable="true">
              </tree-select>
              <div class="debug-output">
                <strong>选中的节点 (简化后):</strong>
                <pre>{{ selectIds8 | json }}</pre>
                <div style="margin-top: 10px; padding: 8px; background: #f0f0f0; border-radius: 4px; font-size: 12px;">
                  <strong>初始值说明:</strong> 预设选中"M1-1" (技术部)<br>
                  <strong>期望行为:</strong><br>
                  1. 加载时应显示 "已选 N 项" (技术部及其所有子部门)<br>
                  2. 打开下拉时，技术部及其子节点应全部勾选<br>
                  3. cascadeReturnParentOnly=true 时，返回 ["M1-1"]<br>
                  4. 支持清空按钮
                </div>
                <div style="margin-top: 10px; padding: 8px; background: #e6f7ff; border-radius: 4px; font-size: 12px;">
                  <strong>调试信息:</strong><br>
                  <span>选中节点数量: {{ selectIds8.length }}</span><br>
                  <span>数据加载状态: {{ treeData2 ? '已加载 (' + treeData2.length + ' 个根节点)' : '未加载' }}</span>
                </div>
              </div>
            </div>
          </div>

          <div class="code-block" style="margin-top: 30px;">
            <code>
// HTML 使用方式<br>
&lt;tree-select<br>
&nbsp;&nbsp;tree-data="treeData"<br>
&nbsp;&nbsp;id="BpaId"<br>
&nbsp;&nbsp;label="cnName"<br>
&nbsp;&nbsp;multiple="true"<br>
&nbsp;&nbsp;cascade="true"<br>
&nbsp;&nbsp;cascade-return-parent-only="false"<br>
&nbsp;&nbsp;ng-model="selectedIds"<br>
&nbsp;&nbsp;placeholder="请选择"<br>
&nbsp;&nbsp;clearable="true"&gt;<br>
&lt;/tree-select&gt;<br>
<br>
// Controller 中<br>
$scope.selectedIds = []; // 选中的节点ID数组
            </code>
          </div>
      </div>
    </div>

      <!-- Select Demo -->
      <div class="tab-content" ng-class="{active: activeTab === 'select'}">
        <div class="demo-section">
          <h2>下拉选择组件</h2>

          <div class="feature-list">
            <strong>功能特性:</strong>
            <ul>
              <li>单选/多选模式，支持配置值与标签字段</li>
              <li>本地搜索与远程搜索结合，自动高亮关键字</li>
              <li>多选标签支持单个删除、批量清空与占位符提示</li>
              <li>支持禁用状态、清空按钮、自定义占位符等</li>
            </ul>
          </div>

          <div class="select-demo-grid">
            <div class="select-demo-item">
              <h3>1. 基本单选</h3>
              <p>设置默认值并允许一键清空</p>
              <ng-select
                options="cityOptions"
                ng-model="selectedCity"
                placeholder="请选择城市"
                clearable="true">
              </ng-select>
              <div class="debug-output">
                <strong>选中的值:</strong>
                <pre>{{ selectedCity | json }}</pre>
              </div>
            </div>

            <div class="select-demo-item">
              <h3>2. 可搜索单选</h3>
              <p>启用本地搜索，关键字自动高亮</p>
              <ng-select
                options="cityOptions"
                ng-model="selectedSearchableCity"
                placeholder="搜索或选择城市"
                searchable="true"
                search-placeholder="输入关键字搜索"
                clearable="true">
              </ng-select>
              <div class="debug-output">
                <strong>选中的值:</strong>
                <pre>{{ selectedSearchableCity | json }}</pre>
              </div>
            </div>

            <div class="select-demo-item">
              <h3>3. 多选标签</h3>
              <p>多选模式下，支持单个标签删除</p>
              <ng-select
                options="frameworkOptions"
                ng-model="selectedFrameworks"
                multiple="true"
                placeholder="请选择技术栈"
                clearable="true"
                value-field="id"
                label-field="label">
              </ng-select>
              <div class="debug-output">
                <strong>选中的值:</strong>
                <pre>{{ selectedFrameworks | json }}</pre>
              </div>
            </div>

            <div class="select-demo-item">
              <h3>4. 远程搜索（单选）</h3>
              <p>输入关键字触发远程搜索，支持加载状态</p>
              <ng-select
                options="remoteDefaultOptions"
                ng-model="selectedCountry"
                placeholder="搜索国家"
                searchable="true"
                clearable="true"
                remote-search="remoteSearchCountries(keyword)"
                value-field="code"
                label-field="name"
                search-placeholder="输入关键字搜索国家">
              </ng-select>
              <div class="debug-output">
                <strong>选中的值:</strong>
                <pre>{{ selectedCountry | json }}</pre>
              </div>
            </div>

            <div class="select-demo-item">
              <h3>5. 远程搜索（多选）</h3>
              <p>结合多选与远程搜索，演示单个标签删除</p>
              <ng-select
                options="remoteDefaultOptions"
                ng-model="selectedCountryList"
                multiple="true"
                placeholder="搜索选择多个国家"
                searchable="true"
                clearable="true"
                remote-search="remoteSearchCountries(keyword)"
                value-field="code"
                label-field="name"
                search-placeholder="输入关键字搜索国家">
              </ng-select>
              <div class="debug-output">
                <strong>选中的值:</strong>
                <pre>{{ selectedCountryList | json }}</pre>
              </div>
            </div>

            <div class="select-demo-item">
              <h3>6. 禁用状态</h3>
              <p>展示组件在禁用情况下的视觉反馈</p>
              <ng-select
                options="cityOptions"
                ng-model="selectedDisabledCity"
                placeholder="组件已禁用"
                disabled="true"
                clearable="true">
              </ng-select>
              <div class="debug-output">
                <strong>选中的值:</strong>
                <pre>{{ selectedDisabledCity | json }}</pre>
              </div>
            </div>
          </div>

          <div class="code-block" style="margin-top: 30px;">
            <code>
// 单选<br>
&lt;ng-select<br>
&nbsp;&nbsp;options="options"<br>
&nbsp;&nbsp;ng-model="value"<br>
&nbsp;&nbsp;placeholder="请选择"<br>
&nbsp;&nbsp;clearable="true"<br>
&nbsp;&nbsp;searchable="true"&gt;<br>
&lt;/ng-select&gt;<br>
<br>
// 多选 + 远程搜索<br>
&lt;ng-select<br>
&nbsp;&nbsp;options="options"<br>
&nbsp;&nbsp;ng-model="values"<br>
&nbsp;&nbsp;multiple="true"<br>
&nbsp;&nbsp;remote-search="searchRemote(keyword)"<br>
&nbsp;&nbsp;value-field="id"<br>
&nbsp;&nbsp;label-field="label"&gt;<br>
&lt;/ng-select&gt;<br>
            </code>
          </div>
        </div>
      </div>

      <!-- DatePicker Demo -->
      <div class="tab-content" ng-class="{active: activeTab === 'datePicker'}">
        <div class="demo-section">
          <h2>日期选择组件</h2>

          <div class="feature-list">
            <strong>功能特性:</strong>
            <ul>
              <li>支持字符串或 Date 对象作为 ngModel，自动匹配返回类型</li>
              <li>提供最小/最大日期限制，支持快速选择今天与清空</li>
              <li>可自定义日期格式、起始周设置、禁用状态与占位符</li>
              <li>轻量纯前端实现，无第三方依赖</li>
            </ul>
          </div>

          <div class="date-demo-grid">
            <div class="date-demo-item">
              <h3>1. 基本用法</h3>
              <p>默认返回 Date 对象，带清空与“今天”按钮</p>
              <ng-date-picker
                ng-model="selectedDate"
                placeholder="请选择日期"
                clearable="true">
              </ng-date-picker>
              <div class="debug-output">
                <strong>选中的值 (Date):</strong>
                <pre>{{ selectedDate | json }}</pre>
              </div>
            </div>

            <div class="date-demo-item">
              <h3>2. 字符串输出 + 自定义格式</h3>
              <p>初始值为字符串时，组件会保持字符串格式</p>
              <ng-date-picker
                ng-model="birthdayString"
                placeholder="请选择生日"
                format="YYYY/MM/DD"
                clearable="true">
              </ng-date-picker>
              <div class="debug-output">
                <strong>选中的值 (String):</strong>
                <pre>{{ birthdayString | json }}</pre>
              </div>
            </div>

            <div class="date-demo-item">
              <h3>3. 限制范围</h3>
              <p>仅允许选择本月范围内的日期</p>
              <ng-date-picker
                ng-model="projectStart"
                placeholder="项目开始时间"
                min-date="rangeStart"
                max-date="rangeEnd"
                clearable="true"
                show-today="false">
              </ng-date-picker>
              <div class="debug-output">
                <strong>选中的值:</strong>
                <pre>{{ projectStart | json }}</pre>
              </div>
            </div>

            <div class="date-demo-item">
              <h3>4. 周一为一周开始</h3>
              <p>切换周起始日，示例同时展示禁用状态</p>
              <div style="display: flex; gap: 12px; flex-wrap: wrap;">
                <ng-date-picker
                  ng-model="meetingDay"
                  placeholder="请选择会议日期"
                  start-week-on-monday="true"
                  clearable="true">
                </ng-date-picker>
                <ng-date-picker
                  ng-model="lockedDate"
                  placeholder="当前不可编辑"
                  disabled="true"
                  clearable="true">
                </ng-date-picker>
              </div>
              <div class="debug-output">
                <strong>会议日期:</strong>
                <pre>{{ meetingDay | json }}</pre>
              </div>
            </div>
          </div>

          <div class="code-block" style="margin-top: 30px;">
            <code>
// 基本用法<br>
&lt;ng-date-picker ng-model="value" placeholder="请选择日期"&gt;&lt;/ng-date-picker&gt;<br>
<br>
// 指定返回字符串<br>
$scope.birthdayString = "1991/05/20";<br>
&lt;ng-date-picker ng-model="birthdayString" format="YYYY/MM/DD"&gt;&lt;/ng-date-picker&gt;<br>
<br>
// 限制范围 + 自定义周起始<br>
&lt;ng-date-picker<br>
&nbsp;&nbsp;ng-model="startDate"<br>
&nbsp;&nbsp;min-date="rangeStart"<br>
&nbsp;&nbsp;max-date="rangeEnd"<br>
&nbsp;&nbsp;start-week-on-monday="true"&gt;<br>
&lt;/ng-date-picker&gt;
            </code>
          </div>
      </div>
    </div>

      <!-- Image Preview Demo -->
      <div class="tab-content" ng-class="{active: activeTab === 'imagePreview'}">
        <div class="demo-section">
          <h2>图片预览组件</h2>

          <div class="feature-list">
            <strong>功能特性:</strong>
            <ul>
              <li>双击图片即可全屏预览</li>
              <li>支持设置高清原图与标题文案</li>
              <li>提供放大、缩小、重置缩放的便捷控制</li>
              <li>点击背景或按下 Esc 键即可关闭</li>
            </ul>
          </div>

          <div class="image-preview-grid">
            <div class="image-preview-card" ng-repeat="item in previewImages">
              <h3>{{ item.title }}</h3>
              <p>{{ item.desc }}</p>
              <img
                ng-image-preview
                ng-src="{{ item.thumb }}"
                preview-src="{{ item.full }}"
                preview-title="{{ item.title }}"
                preview-alt="{{ item.title }}"
                alt="{{ item.title }}"
              />
            </div>

            <div class="image-preview-card">
              <h3>禁用切换</h3>
              <p>通过 <code>preview-disabled</code> 控制是否允许预览</p>
              <div class="image-preview-controls">
                <label>
                  <input type="checkbox" ng-model="imagePreviewDisabled" />
                  禁用预览
                </label>
              </div>
              <img
                ng-image-preview
                preview-disabled="imagePreviewDisabled"
                ng-src="{{ previewImages[0].thumb }}"
                preview-src="{{ previewImages[0].full }}"
                preview-title="禁用切换示例"
                alt="禁用切换示例"
              />
            </div>
          </div>

          <div class="code-block" style="margin-top: 30px;">
            <code>
// 基本用法<br>
&lt;img ng-image-preview src="thumb.jpg" preview-src="full.jpg" preview-title="风景"&gt;<br>
<br>
// 禁用预览<br>
&lt;img ng-image-preview src="thumb.jpg" preview-disabled="isDisabled"&gt;
            </code>
          </div>
        </div>
      </div>

      <!-- Toast Demo -->
      <div class="tab-content" ng-class="{active: activeTab === 'toast'}">
        <div class="demo-section">
          <h2>通知提示组件</h2>

          <div class="feature-list">
            <strong>功能特性:</strong>
            <ul>
              <li>提供 info/success/warning/danger 四类状态，支持自定义图标与样式</li>
              <li>支持自动消失、手动关闭、批量清空、弹窗数量上限</li>
              <li>多种停靠位置选择，可按需放置多个容器</li>
              <li>与 `$confirm` 一样，API 简洁易用</li>
            </ul>
          </div>

          <div class="toast-demo-actions">
            <button class="btn btn-success" ng-click="showToastSuccess()">成功提示</button>
            <button class="btn btn-info" ng-click="showToastInfo()">信息提示</button>
            <button class="btn btn-warning" ng-click="showToastWarning()">警告提示</button>
            <button class="btn btn-danger" ng-click="showToastDanger()">错误提示</button>
            <button class="btn btn-primary" ng-click="showToastCustom()">自定义内容</button>
            <button class="btn" style="background:#4b5563;color:#fff;" ng-click="stackToast()">快速堆叠</button>
            <button class="btn" style="background:#1f2937;color:#fff;" ng-click="clearToasts()">清空全部</button>
          </div>

          <div class="debug-output">
            <strong>当前 Toast 数量: {{ getToastCount() }}</strong>
            <pre>{{ toastHistory | json }}</pre>
          </div>

          <div class="code-block" style="margin-top: 30px;">
            <code>
// 在模板中放置容器<br>
&lt;ng-toast-container placement="top-right"&gt;&lt;/ng-toast-container&gt;<br>
<br>
// 在 Controller 中注入 ngToast<br>
ngToast.success('保存成功');<br>
ngToast.show({<br>
&nbsp;&nbsp;title: '系统通知',<br>
&nbsp;&nbsp;message: '五秒后自动关闭',<br>
&nbsp;&nbsp;type: 'info',<br>
&nbsp;&nbsp;duration: 5000<br>
});<br>
<br>
// 清空全部<br>
ngToast.clearAll();
            </code>
          </div>
      </div>
    </div>

      <!-- Angular-Strap Demo -->
      <div class="tab-content" ng-class="{active: activeTab === 'strap'}">
        <a href="angular-strap.html" class="standalone-link">查看独立演示页</a>
        <div class="strap-demo" bs-affix-target id="strap-demo">
          <div class="strap-nav">
            <ul
              class="nav nav-pills nav-stacked strap-nav-list"
              bs-scrollspy-list
              bs-affix
              data-offset-top="140"
            >
              <li
                ng-repeat="nav in strapNavItems track by nav.id"
                ng-class="{active: activeStrapSection === nav.id}"
              >
                <a
                  href="#{{ nav.id }}"
                  ng-click="scrollToStrapSection(nav.id, $event)"
                >
                  {{ nav.label }}
                </a>
              </li>
            </ul>
          </div>
          <div class="strap-content" id="strap-content">
            <section id="strap-overview" class="demo-section strap-section">
              <h2>Angular-Strap 组件概览</h2>
              <p>
                Angular-Strap 为 AngularJS 带来了完整的 Bootstrap 交互合集，指令命名以
                <code>bs-*</code> 开头，可与现有组件同时使用。
              </p>
              <p>
                左侧导航即通过 <code>bs-affix</code> 与 <code>bs-scrollspy</code> 实现吸顶和锚点高亮，下方章节分别展示核心组件。
              </p>
              <div class="feature-list">
                <strong>包含组件:</strong>
                <ul>
                  <li>Alert、Aside、Modal、Dropdown、Popover、Tooltip</li>
                  <li>Button 组（bs-checkbox / bs-radio）、Collapse、Tabs</li>
                  <li>Select、Datepicker、Timepicker、Typeahead</li>
                  <li>Navbar、Affix、Scrollspy 等导航辅助指令</li>
                </ul>
              </div>
            </section>

            <section id="strap-alert" class="demo-section strap-section">
              <h2>Alert 警告组件</h2>
              <p>通过注入 <code>$alert</code> 服务即可弹出带动画的提示信息，内置四种语义类型并支持定时自动关闭。</p>
              <div class="strap-example">
                <button class="btn btn-success" ng-click="openStrapAlert('success')">成功提示</button>
                <button class="btn btn-info" ng-click="openStrapAlert('info')">信息提示</button>
                <button class="btn btn-warning" ng-click="openStrapAlert('warning')">警告提示</button>
                <button class="btn btn-danger" ng-click="openStrapAlert('danger')">危险提示</button>
              </div>
              <div class="code-block">
                <code>
$scope.openStrapAlert = function(type) {<br>
&nbsp;&nbsp;$alert({<br>
&nbsp;&nbsp;&nbsp;&nbsp;title: '状态提醒',<br>
&nbsp;&nbsp;&nbsp;&nbsp;content: '操作结果反馈',<br>
&nbsp;&nbsp;&nbsp;&nbsp;type: type,<br>
&nbsp;&nbsp;&nbsp;&nbsp;placement: 'top',<br>
&nbsp;&nbsp;&nbsp;&nbsp;container: 'body',<br>
&nbsp;&nbsp;&nbsp;&nbsp;duration: 3,<br>
&nbsp;&nbsp;&nbsp;&nbsp;show: true<br>
&nbsp;&nbsp;});<br>
};<br>
                </code>
              </div>
            </section>

            <section id="strap-aside" class="demo-section strap-section">
              <h2>Aside 侧边抽屉</h2>
              <p><code>bs-aside</code> 指令可以从任意方向滑出携带标题与内容的抽屉，和模态框共享同一套配置。</p>
              <div class="strap-example">
                <button
                  class="btn btn-default"
                  bs-aside
                  data-placement="left"
                  data-animation="am-slide-left"
                  data-title="消息中心"
                  data-content="在这里展示侧栏内容或者操作表单。"
                >
                  从左侧打开
                </button>
                <button
                  class="btn btn-default"
                  bs-aside
                  data-placement="right"
                  data-animation="am-slide-right"
                  data-title="快速设置"
                  data-content="支持设置 backdrop、keyboard 等属性。"
                >
                  从右侧打开
                </button>
              </div>
              <div class="code-block">
                <code>
&lt;button class="btn btn-default"<br>
&nbsp;&nbsp;bs-aside<br>
&nbsp;&nbsp;data-placement="left"<br>
&nbsp;&nbsp;data-animation="am-slide-left"<br>
&nbsp;&nbsp;data-title="消息中心"<br>
&nbsp;&nbsp;data-content="支持 HTML 模板"&gt;打开抽屉&lt;/button&gt;
                </code>
              </div>
            </section>

            <section id="strap-modal" class="demo-section strap-section">
              <h2>Modal 模态框</h2>
              <p><code>bs-modal</code> 提供高度可定制的弹窗。可以直接设置标题/内容，或者指定自定义模板。</p>
              <div class="strap-example">
                <button
                  class="btn btn-primary"
                  bs-modal
                  data-animation="am-fade-and-slide-top"
                  data-title="审批提醒"
                  data-content="这是使用默认模板渲染的模态框内容。"
                >
                  标准模态框
                </button>
                <button
                  class="btn btn-info"
                  bs-modal
                  data-template="strap/custom-modal.tpl.html"
                  data-backdrop="static"
                  data-animation="am-scale"
                >
                  自定义模板
                </button>
              </div>
              <div class="code-block">
                <code>
&lt;button class="btn btn-primary"<br>
&nbsp;&nbsp;bs-modal<br>
&nbsp;&nbsp;data-title="审批提醒"<br>
&nbsp;&nbsp;data-content="默认模板内容"&gt;打开&lt;/button&gt;<br>
<br>
&lt;button class="btn btn-info"<br>
&nbsp;&nbsp;bs-modal<br>
&nbsp;&nbsp;data-template="strap/custom-modal.tpl.html"<br>
&nbsp;&nbsp;data-backdrop="static"&gt;自定义&lt;/button&gt;
                </code>
              </div>
            </section>

            <section id="strap-dropdown" class="demo-section strap-section">
              <h2>Dropdown 下拉菜单</h2>
              <p><code>bs-dropdown</code> 能快速把任意按钮组变成 Bootstrap 风格菜单，并保持 Angular 绑定。</p>
              <div class="strap-example">
                <div class="btn-group" bs-dropdown>
                  <button class="btn btn-default dropdown-toggle">
                    {{ strapDropdownSelected }} <span class="caret"></span>
                  </button>
                  <ul class="dropdown-menu" role="menu">
                    <li ng-repeat="item in strapDropdownItems">
                      <a href="" ng-click="selectDropdown(item.label)">{{ item.label }}</a>
                    </li>
                  </ul>
                </div>
                <span class="text-muted">当前选择：{{ strapDropdownSelected }}</span>
              </div>
              <div class="code-block">
                <code>
&lt;div class="btn-group" bs-dropdown&gt;<br>
&nbsp;&nbsp;&lt;button class="btn btn-default dropdown-toggle"&gt;操作&lt;span class="caret"&gt;&lt;/span&gt;&lt;/button&gt;<br>
&nbsp;&nbsp;&lt;ul class="dropdown-menu"&gt;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&lt;li ng-repeat="item in items"&gt;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;a href="" ng-click="select(item)"&gt;&#123;&#123;item&#125;&#125;&lt;/a&gt;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&lt;/li&gt;<br>
&nbsp;&nbsp;&lt;/ul&gt;<br>
&lt;/div&gt;
                </code>
              </div>
            </section>

            <section id="strap-popover" class="demo-section strap-section">
              <h2>Popover 气泡卡片</h2>
              <p>通过 <code>bs-popover</code> 可在聚焦或点击时展示提示卡片，支持 HTML 内容以及自定义触发方式。</p>
              <div class="strap-example">
                <button
                  class="btn btn-warning"
                  bs-popover
                  data-title="升级提示"
                  data-content="<p>支持 <strong>HTML</strong> 内容与自定义模板。</p>"
                  data-html="true"
                  data-placement="right"
                >
                  悬浮查看 Popover
                </button>
              </div>
              <div class="code-block">
                <code>
&lt;button class="btn btn-warning"<br>
&nbsp;&nbsp;bs-popover<br>
&nbsp;&nbsp;data-title="提示"<br>
&nbsp;&nbsp;data-content="&amp;lt;p&amp;gt;支持 &amp;lt;strong&amp;gt;HTML&amp;lt;/strong&amp;gt;&amp;lt;/p&amp;gt;"<br>
&nbsp;&nbsp;data-html="true"&gt;Popover&lt;/button&gt;
                </code>
              </div>
            </section>

            <section id="strap-tooltip" class="demo-section strap-section">
              <h2>Tooltip 提示</h2>
              <p><code>bs-tooltip</code> 提供轻量提示气泡，可配置触发方式、延迟与方向。</p>
              <div class="strap-example strap-inline">
                <button class="btn btn-default" bs-tooltip data-title="默认提示">默认</button>
                <button class="btn btn-default" bs-tooltip data-title="延迟 1s 出现" data-delay="1000">延迟触发</button>
                <button class="btn btn-default" bs-tooltip data-title="顶部提示" data-placement="top">顶部</button>
                <button class="btn btn-default" bs-tooltip data-title="左侧提示" data-placement="left">左侧</button>
              </div>
              <div class="code-block">
                <code>
&lt;button class="btn btn-default"<br>
&nbsp;&nbsp;bs-tooltip<br>
&nbsp;&nbsp;data-placement="left"<br>
&nbsp;&nbsp;data-delay="500"<br>
&nbsp;&nbsp;data-title="提示内容"&gt;Tooltip&lt;/button&gt;
                </code>
              </div>
            </section>

            <section id="strap-button" class="demo-section strap-section">
              <h2>Button 组切换</h2>
              <p><code>bs-checkbox</code> 与 <code>bs-radio</code> 让按钮充当复选/单选，保持 Bootstrap 样式同步。</p>
              <div class="strap-example">
                <label>复选组：</label>
                <div class="btn-group" bs-checkbox-group ng-model="strapCheckboxes">
                  <label class="btn btn-default" bs-checkbox ng-model="strapCheckboxes.analytics">分析</label>
                  <label class="btn btn-default" bs-checkbox ng-model="strapCheckboxes.reports">报表</label>
                  <label class="btn btn-default" bs-checkbox ng-model="strapCheckboxes.notify">通知</label>
                </div>
                <p class="text-muted">选中值：{{ strapCheckboxes | json }}</p>
                <label>单选组：</label>
                <div class="btn-group" bs-radio-group>
                  <label class="btn btn-default" bs-radio ng-model="strapRadioValue" value="daily">日报</label>
                  <label class="btn btn-default" bs-radio ng-model="strapRadioValue" value="weekly">周报</label>
                  <label class="btn btn-default" bs-radio ng-model="strapRadioValue" value="monthly">月报</label>
                </div>
                <p class="text-muted">当前选择：{{ strapRadioValue }}</p>
              </div>
              <div class="code-block">
                <code>
&lt;div class="btn-group" bs-checkbox-group ng-model="checkboxes"&gt;<br>
&nbsp;&nbsp;&lt;label class="btn btn-default" bs-checkbox ng-model="checkboxes.a"&gt;A&lt;/label&gt;<br>
&nbsp;&nbsp;&lt;label class="btn btn-default" bs-checkbox ng-model="checkboxes.b"&gt;B&lt;/label&gt;<br>
&lt;/div&gt;
                </code>
              </div>
            </section>

            <section id="strap-collapse" class="demo-section strap-section">
              <h2>Collapse 折叠面板</h2>
              <p><code>bs-collapse</code> 可构建手风琴效果，支持单开、多开以及动画配置。</p>
              <div class="strap-example">
                <div class="panel-group" bs-collapse ng-model="strapCollapse.active">
                  <div class="panel panel-default" ng-repeat="item in strapCollapse.sections track by $index">
                    <div class="panel-heading">
                      <h4 class="panel-title">
                        <a href="" bs-collapse-toggle="{{$index}}">
                          {{ item.title }}
                        </a>
                      </h4>
                    </div>
                    <div class="panel-collapse collapse" bs-collapse-target>
                      <div class="panel-body">
                        {{ item.content }}
                      </div>
                    </div>
                  </div>
                </div>
              </div>
              <div class="code-block">
                <code>
&lt;div class="panel-group" bs-collapse ng-model="active"&gt;<br>
&nbsp;&nbsp;&lt;div class="panel panel-default" ng-repeat="section in sections"&gt;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&lt;div class="panel-heading"&gt;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;a href="" bs-collapse-toggle="&#123;&#123;$index&#125;&#125;"&gt;&#123;&#123;section.title&#125;&#125;&lt;/a&gt;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&lt;/div&gt;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&lt;div class="panel-collapse collapse" bs-collapse-target&gt;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;div class="panel-body"&gt;&#123;&#123;section.content&#125;&#125;&lt;/div&gt;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&lt;/div&gt;<br>
&nbsp;&nbsp;&lt;/div&gt;<br>
&lt;/div&gt;
                </code>
              </div>
            </section>

            <section id="strap-tabs" class="demo-section strap-section">
              <h2>Tabs 标签页</h2>
              <p><code>bs-tabs</code> 结合 <code>bs-pane</code> 构建动态标签，支持使用 <code>ng-repeat</code> 渲染。</p>
              <div class="strap-example">
                <div bs-tabs bs-active-pane="strapTabs.active">
                  <div bs-pane title="运行概况">
                    <p>系统运行时间：{{ strapTabs.stats.uptime }}</p>
                  </div>
                  <div bs-pane title="任务队列">
                    <p>排队任务：{{ strapTabs.stats.queue }}</p>
                  </div>
                  <div bs-pane title="错误日志">
                    <p>近 24 小时错误：{{ strapTabs.stats.errors }}</p>
                  </div>
                </div>
              </div>
              <div class="code-block">
                <code>
&lt;div bs-tabs bs-active-pane="activeTab"&gt;<br>
&nbsp;&nbsp;&lt;div bs-pane title="概览"&gt;内容&lt;/div&gt;<br>
&nbsp;&nbsp;&lt;div bs-pane title="日志"&gt;内容&lt;/div&gt;<br>
&lt;/div&gt;
                </code>
              </div>
            </section>

            <section id="strap-select" class="demo-section strap-section">
              <h2>Select 选择器</h2>
              <p><code>bs-select</code> 让按钮/输入框具备搜索与多选能力，API 与 <code>ng-options</code> 相似。</p>
              <div class="strap-example">
                <div class="strap-inline">
                  <button
                    type="button"
                    class="btn btn-default"
                    ng-model="strapSelect.single"
                    bs-select
                    data-placeholder="选择地区"
                    bs-options="region.value as region.label group by region.group for region in strapSelect.options"
                  >
                    单选：{{ strapSelect.single || '未选择' }}
                  </button>
                  <button
                    type="button"
                    class="btn btn-default"
                    ng-model="strapSelect.multiple"
                    bs-select
                    data-multiple="1"
                    data-placeholder="选择标签"
                    bs-options="tag.value as tag.label for tag in strapSelect.tags"
                  >
                    多选：{{ strapSelect.multiple.join(', ') || '未选择' }}
                  </button>
                </div>
              </div>
              <div class="code-block">
                <code>
&lt;button class="btn btn-default"<br>
&nbsp;&nbsp;ng-model="selected"<br>
&nbsp;&nbsp;bs-select<br>
&nbsp;&nbsp;bs-options="item.value as item.label for item in items"&gt;<br>
&nbsp;&nbsp;&#123;&#123;selected || '请选择'&#125;&#125;<br>
&lt;/button&gt;
                </code>
              </div>
            </section>

            <section id="strap-datepicker" class="demo-section strap-section">
              <h2>Datepicker / Timepicker</h2>
              <p>Angular-Strap 提供与 Bootstrap 风格一致的日期、时间选择器，支持双向绑定与格式化。</p>
              <div class="strap-example strap-inline">
                <div>
                  <label>日期：</label>
                  <input
                    type="text"
                    class="form-control strap-form-control"
                    ng-model="strapDate"
                    bs-datepicker
                    data-date-format="yyyy-MM-dd"
                    data-autoclose="1"
                  />
                </div>
                <div>
                  <label>时间：</label>
                  <input
                    type="text"
                    class="form-control strap-form-control"
                    ng-model="strapTime"
                    bs-timepicker
                    data-minute-step="5"
                    data-show-seconds="false"
                  />
                </div>
                <div>
                  <p class="text-muted">当前值：{{ strapDate | date:'yyyy-MM-dd' }} {{ strapTime | date:'HH:mm' }}</p>
                </div>
              </div>
              <div class="code-block">
                <code>
&lt;input type="text"<br>
&nbsp;&nbsp;ng-model="pickedDate"<br>
&nbsp;&nbsp;bs-datepicker<br>
&nbsp;&nbsp;data-autoclose="1"<br>
&nbsp;&nbsp;data-date-format="yyyy-MM-dd"&gt;<br>
<br>
&lt;input type="text"<br>
&nbsp;&nbsp;ng-model="pickedTime"<br>
&nbsp;&nbsp;bs-timepicker<br>
&nbsp;&nbsp;data-minute-step="5"&gt;
                </code>
              </div>
            </section>

            <section id="strap-typeahead" class="demo-section strap-section">
              <h2>Typeahead 自动补全</h2>
              <p><code>bs-typeahead</code> 利用 <code>bs-options</code> 语法提供关键字联想，并可结合 <code>limit</code>、<code>filter</code> 等参数。</p>
              <div class="strap-example strap-inline">
                <input
                  type="text"
                  class="form-control strap-form-control"
                  placeholder="输入州名称"
                  ng-model="strapTypeaheadValue"
                  bs-typeahead
                  bs-options="state for state in strapTypeaheadStates"
                  data-min-length="1"
                />
                <p class="text-muted">选中值：{{ strapTypeaheadValue }}</p>
              </div>
              <div class="code-block">
                <code>
&lt;input type="text"<br>
&nbsp;&nbsp;ng-model="keyword"<br>
&nbsp;&nbsp;bs-typeahead<br>
&nbsp;&nbsp;bs-options="option for option in options"<br>
&nbsp;&nbsp;data-min-length="1"&gt;
                </code>
              </div>
            </section>

            <section id="strap-navbar" class="demo-section strap-section">
              <h2>Navbar 导航条</h2>
              <p><code>bs-navbar</code> 根据 <code>$location.path()</code> 自动高亮匹配路由，可结合自定义链接动作。</p>
              <div class="strap-example">
                <nav class="navbar navbar-default" bs-navbar>
                  <div class="container-fluid">
                    <ul class="nav navbar-nav">
                      <li data-match-route="/dashboard">
                        <a href="" ng-click="setStrapRoute('/dashboard')">仪表盘</a>
                      </li>
                      <li data-match-route="/projects">
                        <a href="" ng-click="setStrapRoute('/projects')">项目</a>
                      </li>
                      <li data-match-route="/reports">
                        <a href="" ng-click="setStrapRoute('/reports')">报表</a>
                      </li>
                    </ul>
                  </div>
                </nav>
                <p class="text-muted">当前路径：{{ strapCurrentRoute }}</p>
              </div>
              <div class="code-block">
                <code>
&lt;nav class="navbar navbar-default" bs-navbar&gt;<br>
&nbsp;&nbsp;&lt;ul class="nav navbar-nav"&gt;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&lt;li data-match-route="/dashboard"&gt;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;a href="" ng-click="setRoute('/dashboard')"&gt;仪表盘&lt;/a&gt;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&lt;/li&gt;<br>
&nbsp;&nbsp;&lt;/ul&gt;<br>
&lt;/nav&gt;
                </code>
              </div>
            </section>

            <section id="strap-affix" class="demo-section strap-section">
              <h2>Affix &amp; Scrollspy</h2>
              <p>本页左侧目录启用了 <code>bs-affix</code> 让导航条在滚动时固定，并通过 <code>bs-scrollspy-list</code> 自动监听锚点激活状态。</p>
              <div class="strap-example">
                <pre style="margin:0;"><code>
&lt;div class="strap-nav"&gt;
&nbsp;&nbsp;&lt;ul class="nav nav-pills"
&nbsp;&nbsp;&nbsp;&nbsp;bs-scrollspy-list
&nbsp;&nbsp;&nbsp;&nbsp;bs-affix
&nbsp;&nbsp;&nbsp;&nbsp;data-offset-top="140"&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&lt;li&gt;&lt;a href="#strap-alert"&gt;Alert&lt;/a&gt;&lt;/li&gt;
&nbsp;&nbsp;&nbsp;&nbsp;... 
&nbsp;&nbsp;&lt;/ul&gt;
&lt;/div&gt;
                </code></pre>
              </div>
              <p class="text-muted">滚动页面时可以观察导航高亮如何随着内容切换。</p>
            </section>
          </div>
        </div>
      </div>

      <!-- Radio Demo -->
      <div class="tab-content" ng-class="{active: activeTab === 'radio'}">
        <div class="demo-section">
          <a href="radio.html" class="standalone-link">查看独立演示页</a>

          <h2>单选框组件</h2>

          <div class="feature-list">
            <strong>功能特性:</strong>
            <ul>
              <li>支持水平和垂直布局</li>
              <li>支持禁用整个组件或单个选项</li>
              <li>支持字符串数组或对象数组作为选项</li>
              <li>双向数据绑定</li>
              <li>优雅的选中/悬停效果</li>
              <li>响应式设计</li>
            </ul>
          </div>

          <div class="tree-demo-grid">
            <!-- Demo 1: 基本水平布局 -->
            <div class="tree-demo-item">
              <h3>1. 基本水平布局</h3>
              <p>默认水平排列的单选框</p>
              <ng-radio
                options="radioOptions1"
                ng-model="radioValue1"
                name="radio1"
                layout="horizontal">
              </ng-radio>
              <div class="debug-output">
                <strong>选中的值:</strong>
                <pre>{{ radioValue1 | json }}</pre>
              </div>
            </div>

            <!-- Demo 2: 垂直布局 -->
            <div class="tree-demo-item">
              <h3>2. 垂直布局</h3>
              <p>选项垂直排列</p>
              <ng-radio
                options="radioOptions1"
                ng-model="radioValue2"
                name="radio2"
                layout="vertical">
              </ng-radio>
              <div class="debug-output">
                <strong>选中的值:</strong>
                <pre>{{ radioValue2 | json }}</pre>
              </div>
            </div>

            <!-- Demo 3: 对象数组选项 -->
            <div class="tree-demo-item">
              <h3>3. 对象数组选项</h3>
              <p>使用 label 和 value 分离的对象数组</p>
              <ng-radio
                options="radioOptions2"
                ng-model="radioValue3"
                name="radio3"
                layout="horizontal">
              </ng-radio>
              <div class="debug-output">
                <strong>选中的值:</strong>
                <pre>{{ radioValue3 | json }}</pre>
              </div>
            </div>

            <!-- Demo 4: 禁用整个组件 -->
            <div class="tree-demo-item">
              <h3>4. 禁用整个组件</h3>
              <p>所有选项都不可选</p>
              <ng-radio
                options="radioOptions1"
                ng-model="radioValue4"
                name="radio4"
                disabled="true"
                layout="horizontal">
              </ng-radio>
              <div class="debug-output">
                <strong>选中的值:</strong>
                <pre>{{ radioValue4 | json }}</pre>
              </div>
            </div>

            <!-- Demo 5: 部分选项禁用 -->
            <div class="tree-demo-item">
              <h3>5. 部分选项禁用</h3>
              <p>某些选项不可选</p>
              <ng-radio
                options="radioOptions3"
                ng-model="radioValue5"
                name="radio5"
                layout="horizontal">
              </ng-radio>
              <div class="debug-output">
                <strong>选中的值:</strong>
                <pre>{{ radioValue5 | json }}</pre>
              </div>
            </div>

            <!-- Demo 6: 带初始值 -->
            <div class="tree-demo-item">
              <h3>6. 带初始值</h3>
              <p>加载时已选中默认值</p>
              <ng-radio
                options="radioOptions1"
                ng-model="radioValue6"
                name="radio6"
                layout="horizontal">
              </ng-radio>
              <div class="debug-output">
                <strong>选中的值:</strong>
                <pre>{{ radioValue6 | json }}</pre>
              </div>
            </div>

            <!-- Demo 7: 数字选项 -->
            <div class="tree-demo-item">
              <h3>7. 数字选项</h3>
              <p>选项值为数字类型</p>
              <ng-radio
                options="radioOptions4"
                ng-model="radioValue7"
                name="radio7"
                layout="horizontal">
              </ng-radio>
              <div class="debug-output">
                <strong>选中的值:</strong>
                <pre>{{ radioValue7 | json }}</pre>
                <div style="margin-top: 10px; padding: 8px; background: #f0f0f0; border-radius: 4px; font-size: 12px;">
                  <strong>类型:</strong> {{ getType(radioValue7) }}
                </div>
              </div>
            </div>

            <!-- Demo 8: 长列表垂直布局 -->
            <div class="tree-demo-item">
              <h3>8. 长列表垂直布局</h3>
              <p>适合较多选项的场景</p>
              <ng-radio
                options="radioOptions5"
                ng-model="radioValue8"
                name="radio8"
                layout="vertical">
              </ng-radio>
              <div class="debug-output">
                <strong>选中的值:</strong>
                <pre>{{ radioValue8 | json }}</pre>
              </div>
            </div>
          </div>

          <div class="code-block" style="margin-top: 30px;">
            <code>
// HTML 使用方式<br>
&lt;ng-radio<br>
&nbsp;&nbsp;options="options"<br>
&nbsp;&nbsp;ng-model="selectedValue"<br>
&nbsp;&nbsp;name="radioGroup"<br>
&nbsp;&nbsp;disabled="false"<br>
&nbsp;&nbsp;layout="horizontal"&gt;<br>
&lt;/ng-radio&gt;<br>
<br>
// Controller 中 - 字符串数组<br>
$scope.options = ['选项1', '选项2', '选项3'];<br>
$scope.selectedValue = '选项1';<br>
<br>
// Controller 中 - 对象数组<br>
$scope.options = [<br>
&nbsp;&nbsp;{ label: '显示文本1', value: 'value1' },<br>
&nbsp;&nbsp;{ label: '显示文本2', value: 'value2', disabled: true },<br>
&nbsp;&nbsp;{ label: '显示文本3', value: 'value3' }<br>
];<br>
$scope.selectedValue = 'value1';
            </code>
          </div>
        </div>
      </div>

      <!-- Resize Demo -->
      <div class="tab-content" ng-class="{active: activeTab === 'resize'}">
        <div class="demo-section">
          <h2>大小缩放组件 (ng-resize)</h2>

          <div class="feature-list">
            <strong>功能特性:</strong>
            <ul>
              <li>为元素添加可拖拽的缩放手柄</li>
              <li>支持四个位置：右下、左上、右上、左下</li>
              <li>支持缩放方向：双向、横向、纵向</li>
              <li>支持最小/最大尺寸限制</li>
              <li>提供缩放回调事件</li>
              <li>流畅的拖拽动画效果</li>
            </ul>
          </div>

          <div class="tree-demo-grid">
            <!-- Demo 1: 基本用法 - 右下角双向缩放 -->
            <div class="tree-demo-item">
              <h3>1. 基本用法（右下角）</h3>
              <p>默认在右下角，支持双向缩放</p>
              <div
                ng-resize
                resize-position="right-bottom"
                resize-direction="both"
                style="width: 300px; height: 200px; background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); color: white; display: flex; align-items: center; justify-content: center; border-radius: 8px; box-shadow: 0 4px 12px rgba(0,0,0,0.15);">
                <div style="text-align: center;">
                  <div style="font-size: 20px; font-weight: bold;">拖拽右下角调整大小</div>
                  <div style="margin-top: 10px; opacity: 0.9;">{{ resizeInfo1.width || 300 }}px × {{ resizeInfo1.height || 200 }}px</div>
                </div>
              </div>
            </div>

            <!-- Demo 2: 左上角缩放 -->
            <div class="tree-demo-item">
              <h3>2. 左上角缩放</h3>
              <p>手柄在左上角</p>
              <div
                ng-resize
                resize-position="left-top"
                resize-direction="both"
                on-resize="updateResizeInfo2(width, height)"
                style="width: 280px; height: 180px; background: linear-gradient(135deg, #f093fb 0%, #f5576c 100%); color: white; display: flex; align-items: center; justify-content: center; border-radius: 8px; box-shadow: 0 4px 12px rgba(0,0,0,0.15);">
                <div style="text-align: center;">
                  <div style="font-size: 18px; font-weight: bold;">拖拽左上角</div>
                  <div style="margin-top: 8px;">{{ resizeInfo2.width || 280 }}px × {{ resizeInfo2.height || 180 }}px</div>
                </div>
              </div>
            </div>

            <!-- Demo 3: 右上角缩放 -->
            <div class="tree-demo-item">
              <h3>3. 右上角缩放</h3>
              <p>手柄在右上角</p>
              <div
                ng-resize
                resize-position="right-top"
                resize-direction="both"
                on-resize="updateResizeInfo3(width, height)"
                style="width: 280px; height: 180px; background: linear-gradient(135deg, #4facfe 0%, #00f2fe 100%); color: white; display: flex; align-items: center; justify-content: center; border-radius: 8px; box-shadow: 0 4px 12px rgba(0,0,0,0.15);">
                <div style="text-align: center;">
                  <div style="font-size: 18px; font-weight: bold;">拖拽右上角</div>
                  <div style="margin-top: 8px;">{{ resizeInfo3.width || 280 }}px × {{ resizeInfo3.height || 180 }}px</div>
                </div>
              </div>
            </div>

            <!-- Demo 4: 左下角缩放 -->
            <div class="tree-demo-item">
              <h3>4. 左下角缩放</h3>
              <p>手柄在左下角</p>
              <div
                ng-resize
                resize-position="left-bottom"
                resize-direction="both"
                on-resize="updateResizeInfo4(width, height)"
                style="width: 280px; height: 180px; background: linear-gradient(135deg, #43e97b 0%, #38f9d7 100%); color: white; display: flex; align-items: center; justify-content: center; border-radius: 8px; box-shadow: 0 4px 12px rgba(0,0,0,0.15);">
                <div style="text-align: center;">
                  <div style="font-size: 18px; font-weight: bold;">拖拽左下角</div>
                  <div style="margin-top: 8px;">{{ resizeInfo4.width || 280 }}px × {{ resizeInfo4.height || 180 }}px</div>
                </div>
              </div>
            </div>

            <!-- Demo 5: 仅纵向缩放 -->
            <div class="tree-demo-item">
              <h3>5. 仅纵向缩放</h3>
              <p>固定底部，向上拖拽增加高度</p>
              <div style="display: flex; flex-direction: column; align-items: flex-start; justify-content: flex-end; min-height: 200px; padding: 20px; border: 1px dashed #ddd; border-radius: 8px;">
                <div
                  ng-resize
                  resize-position="right-top"
                  resize-direction="vertical"
                  on-resize="updateResizeInfo5(width, height)"
                  style="width: 300px; height: 150px; background: linear-gradient(135deg, #30cfd0 0%, #330867 100%); color: white; display: flex; align-items: center; justify-content: center; border-radius: 8px; box-shadow: 0 4px 12px rgba(0,0,0,0.15);">
                  <div style="text-align: center;">
                    <div style="font-size: 18px; font-weight: bold;">固定底部，向上拉高</div>
                    <div style="margin-top: 8px;">高度: {{ resizeInfo5.height || 150 }}px</div>
                  </div>
                </div>
              </div>
            </div>

            <!-- Demo 6: 仅横向缩放 -->
            <div class="tree-demo-item">
              <h3>6. 仅横向缩放</h3>
              <p>只能调整宽度</p>
              <div
                ng-resize
                resize-position="right-bottom"
                resize-direction="horizontal"
                on-resize="updateResizeInfo6(width, height)"
                style="width: 300px; height: 150px; background: linear-gradient(135deg, #fa709a 0%, #fee140 100%); color: white; display: flex; align-items: center; justify-content: center; border-radius: 8px; box-shadow: 0 4px 12px rgba(0,0,0,0.15);">
                <div style="text-align: center;">
                  <div style="font-size: 18px; font-weight: bold;">只能横向拖拽</div>
                  <div style="margin-top: 8px;">宽度: {{ resizeInfo6.width || 300 }}px</div>
                </div>
              </div>
            </div>

            <!-- Demo 7: 带尺寸限制 -->
            <div class="tree-demo-item">
              <h3>7. 带尺寸限制</h3>
              <p>最小 150×100，最大 500×400</p>
              <div
                ng-resize
                resize-position="right-bottom"
                resize-direction="both"
                min-width="150"
                min-height="100"
                max-width="500"
                max-height="400"
                on-resize="updateResizeInfo7(width, height)"
                style="width: 250px; height: 150px; background: linear-gradient(135deg, #a8edea 0%, #fed6e3 100%); color: #333; display: flex; align-items: center; justify-content: center; border-radius: 8px; box-shadow: 0 4px 12px rgba(0,0,0,0.15);">
                <div style="text-align: center;">
                  <div style="font-size: 16px; font-weight: bold;">有尺寸限制</div>
                  <div style="margin-top: 8px; font-size: 14px;">{{ resizeInfo7.width || 250 }}px × {{ resizeInfo7.height || 150 }}px</div>
                  <div style="margin-top: 4px; font-size: 12px; opacity: 0.7;">最小: 150×100 / 最大: 500×400</div>
                </div>
              </div>
            </div>

            <!-- Demo 8: 实际应用场景 - 图片容器 -->
            <div class="tree-demo-item">
              <h3>8. 实际应用 - 图片容器</h3>
              <p>可调整大小的图片预览窗口</p>
              <div
                ng-resize
                resize-position="right-bottom"
                resize-direction="both"
                min-width="200"
                min-height="150"
                on-resize="updateResizeInfo8(width, height)"
                style="width: 300px; height: 200px; border-radius: 8px; overflow: hidden; box-shadow: 0 4px 12px rgba(0,0,0,0.15); background: #f5f5f5;">
                <img src="https://picsum.photos/id/1015/400/300"
                     style="width: 100%; height: 100%; object-fit: cover;"
                     alt="示例图片">
                <div style="position: absolute; bottom: 0; left: 0; right: 0; background: rgba(0,0,0,0.7); color: white; padding: 8px; font-size: 12px;">
                  尺寸: {{ resizeInfo8.width || 300 }}px × {{ resizeInfo8.height || 200 }}px
                </div>
              </div>
            </div>
          </div>

          <div class="code-block" style="margin-top: 30px;">
            <code>
// 基本用法<br>
&lt;div ng-resize<br>
&nbsp;&nbsp;resize-position="right-bottom"<br>
&nbsp;&nbsp;resize-direction="both"<br>
&nbsp;&nbsp;style="width: 300px; height: 200px;"&gt;<br>
&nbsp;&nbsp;内容<br>
&lt;/div&gt;<br>
<br>
// 仅横向缩放<br>
&lt;div ng-resize<br>
&nbsp;&nbsp;resize-position="right-bottom"<br>
&nbsp;&nbsp;resize-direction="horizontal"<br>
&nbsp;&nbsp;style="width: 300px; height: 200px;"&gt;<br>
&nbsp;&nbsp;内容<br>
&lt;/div&gt;<br>
<br>
// 带尺寸限制和回调<br>
&lt;div ng-resize<br>
&nbsp;&nbsp;resize-position="right-bottom"<br>
&nbsp;&nbsp;resize-direction="both"<br>
&nbsp;&nbsp;min-width="150"<br>
&nbsp;&nbsp;min-height="100"<br>
&nbsp;&nbsp;max-width="500"<br>
&nbsp;&nbsp;max-height="400"<br>
&nbsp;&nbsp;on-resize="onResize(width, height)"<br>
&nbsp;&nbsp;style="width: 300px; height: 200px;"&gt;<br>
&nbsp;&nbsp;内容<br>
&lt;/div&gt;<br>
<br>
// Controller 中<br>
$scope.onResize = function(width, height) {<br>
&nbsp;&nbsp;console.log('新尺寸:', width, height);<br>
};
            </code>
          </div>
        </div>
      </div>

      <!-- Loading Demo -->
      <div class="tab-content" ng-class="{active: activeTab === 'loading'}">
        <div class="demo-section">
          <h2>加载动画组件 (ng-loading)</h2>

          <div class="feature-list">
            <strong>功能特性:</strong>
            <ul>
              <li>支持全局加载遮罩（服务模式）</li>
              <li>支持局部加载（指令模式）</li>
              <li>流畅的旋转动画效果</li>
              <li>可自定义加载文字</li>
              <li>可自定义颜色</li>
              <li>支持三种尺寸：small、medium、large</li>
              <li>淡入淡出动画</li>
            </ul>
          </div>

          <h3 style="margin-top: 30px;">一、全局加载（服务模式）</h3>
          <p>通过 $loading 服务调用，覆盖整个页面</p>

          <div class="demo-actions" style="margin: 20px 0;">
            <button class="btn btn-primary" ng-click="showGlobalLoading()">显示全局加载</button>
            <button class="btn btn-success" ng-click="showGlobalLoadingWithText()">带文字的加载</button>
            <button class="btn btn-info" ng-click="showGlobalLoadingCustom()">自定义颜色和尺寸</button>
            <button class="btn btn-danger" ng-click="hideGlobalLoading()">隐藏加载</button>
          </div>

          <h3 style="margin-top: 40px;">二、局部加载（指令模式）</h3>
          <p>使用 ng-loading 指令，仅在特定元素内显示加载</p>

          <div class="tree-demo-grid">
            <!-- Demo 1: 基本用法 -->
            <div class="tree-demo-item">
              <h3>1. 基本用法</h3>
              <p>点击按钮切换加载状态</p>
              <div style="padding: 20px; background: #f5f5f5; border-radius: 8px; min-height: 200px;"
                   ng-loading="loading1">
                <h4>内容区域</h4>
                <p>这是一个示例内容区域。点击下方按钮查看加载效果。</p>
                <button class="btn btn-primary btn-sm" ng-click="toggleLoading(1)">
                  {{ loading1 ? '停止加载' : '开始加载' }}
                </button>
              </div>
            </div>

            <!-- Demo 2: 带加载文字 -->
            <div class="tree-demo-item">
              <h3>2. 带加载文字</h3>
              <p>显示加载提示文字</p>
              <div style="padding: 20px; background: #f0f9ff; border-radius: 8px; min-height: 200px;"
                   ng-loading="loading2"
                   loading-text="正在加载数据...">
                <h4>数据列表</h4>
                <ul>
                  <li>列表项 1</li>
                  <li>列表项 2</li>
                  <li>列表项 3</li>
                </ul>
                <button class="btn btn-info btn-sm" ng-click="toggleLoading(2)">
                  {{ loading2 ? '停止加载' : '开始加载' }}
                </button>
              </div>
            </div>

            <!-- Demo 3: 自定义颜色 -->
            <div class="tree-demo-item">
              <h3>3. 自定义颜色</h3>
              <p>使用紫色主题</p>
              <div style="padding: 20px; background: #faf5ff; border-radius: 8px; min-height: 200px;"
                   ng-loading="loading3"
                   loading-text="加载中..."
                   loading-color="#9333ea">
                <h4>卡片内容</h4>
                <p style="color: #666;">自定义加载动画颜色</p>
                <button class="btn btn-sm" style="background: #9333ea; color: white;" ng-click="toggleLoading(3)">
                  {{ loading3 ? '停止加载' : '开始加载' }}
                </button>
              </div>
            </div>

            <!-- Demo 4: 小尺寸 -->
            <div class="tree-demo-item">
              <h3>4. 小尺寸加载</h3>
              <p>适合小型卡片</p>
              <div style="padding: 15px; background: #fff7ed; border-radius: 8px; min-height: 150px;"
                   ng-loading="loading4"
                   loading-text="加载中"
                   loading-color="#f59e0b"
                   loading-size="small">
                <h4 style="font-size: 16px;">小卡片</h4>
                <button class="btn btn-warning btn-sm" ng-click="toggleLoading(4)">
                  {{ loading4 ? '停止' : '加载' }}
                </button>
              </div>
            </div>

            <!-- Demo 5: 大尺寸 -->
            <div class="tree-demo-item">
              <h3>5. 大尺寸加载</h3>
              <p>适合大型容器</p>
              <div style="padding: 30px; background: #f0fdf4; border-radius: 8px; min-height: 250px;"
                   ng-loading="loading5"
                   loading-text="正在处理，请稍候..."
                   loading-color="#22c55e"
                   loading-size="large">
                <h4>大型内容区</h4>
                <p>这是一个较大的内容区域，使用大尺寸的加载动画更合适。</p>
                <button class="btn btn-success btn-sm" ng-click="toggleLoading(5)">
                  {{ loading5 ? '停止加载' : '开始加载' }}
                </button>
              </div>
            </div>

            <!-- Demo 6: 模拟异步操作 -->
            <div class="tree-demo-item">
              <h3>6. 模拟异步请求</h3>
              <p>3秒后自动完成</p>
              <div style="padding: 20px; background: #fef2f2; border-radius: 8px; min-height: 200px;"
                   ng-loading="loading6"
                   loading-text="正在请求数据..."
                   loading-color="#ef4444">
                <h4>异步数据加载</h4>
                <p ng-if="!asyncData6">点击按钮模拟异步请求</p>
                <p ng-if="asyncData6" style="color: #22c55e; font-weight: bold;">✓ 数据加载成功！</p>
                <button class="btn btn-danger btn-sm" ng-click="simulateAsyncLoad(6)" ng-disabled="loading6">
                  {{ loading6 ? '加载中...' : (asyncData6 ? '重新加载' : '发起请求') }}
                </button>
              </div>
            </div>
          </div>

          <div class="code-block" style="margin-top: 30px;">
            <code>
// 全局加载（服务模式）<br>
<br>
// 简单使用<br>
$loading.show();<br>
$loading.hide();<br>
<br>
// 带文字<br>
$loading.show({ text: '加载中...' });<br>
<br>
// 自定义颜色和尺寸<br>
$loading.show({<br>
&nbsp;&nbsp;text: '处理中...',<br>
&nbsp;&nbsp;color: '#9333ea',<br>
&nbsp;&nbsp;size: 'large' // small, medium, large<br>
});<br>
<br>
// 局部加载（指令模式）<br>
<br>
// 基本用法<br>
&lt;div ng-loading="isLoading"&gt;<br>
&nbsp;&nbsp;内容<br>
&lt;/div&gt;<br>
<br>
// 带文字<br>
&lt;div ng-loading="isLoading"<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;loading-text="加载中..."&gt;<br>
&nbsp;&nbsp;内容<br>
&lt;/div&gt;<br>
<br>
// 自定义颜色和尺寸<br>
&lt;div ng-loading="isLoading"<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;loading-text="处理中..."<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;loading-color="#9333ea"<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;loading-size="large"&gt;<br>
&nbsp;&nbsp;内容<br>
&lt;/div&gt;<br>
<br>
// Controller 中<br>
angular.module('demoApp').controller('DemoCtrl', function($scope, $loading) {<br>
&nbsp;&nbsp;// 全局加载<br>
&nbsp;&nbsp;$scope.showLoading = function() {<br>
&nbsp;&nbsp;&nbsp;&nbsp;$loading.show({ text: '加载中...' });<br>
&nbsp;&nbsp;};<br>
<br>
&nbsp;&nbsp;$scope.hideLoading = function() {<br>
&nbsp;&nbsp;&nbsp;&nbsp;$loading.hide();<br>
&nbsp;&nbsp;};<br>
<br>
&nbsp;&nbsp;// 局部加载<br>
&nbsp;&nbsp;$scope.isLoading = false;<br>
&nbsp;&nbsp;$scope.toggleLoading = function() {<br>
&nbsp;&nbsp;&nbsp;&nbsp;$scope.isLoading = !$scope.isLoading;<br>
&nbsp;&nbsp;};<br>
<br>
&nbsp;&nbsp;// 模拟异步请求<br>
&nbsp;&nbsp;$scope.loadData = function() {<br>
&nbsp;&nbsp;&nbsp;&nbsp;$scope.isLoading = true;<br>
&nbsp;&nbsp;&nbsp;&nbsp;$timeout(function() {<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// 处理数据<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$scope.isLoading = false;<br>
&nbsp;&nbsp;&nbsp;&nbsp;}, 2000);<br>
&nbsp;&nbsp;};<br>
});
            </code>
          </div>
        </div>
      </div>

      <!-- TinyMCE Demo -->
      <div class="tab-content" ng-class="{active: activeTab === 'tinymce'}">
        <div class="demo-section">
          <a href="ng-tinymce.html" class="standalone-link">查看独立演示页</a>

          <h2>富文本编辑器 (TinyMCE)</h2>

          <div class="feature-list">
            <strong>功能特性:</strong>
            <ul>
              <li>指令自动按需加载 TinyMCE 脚本，无需手动引入</li>
              <li>支持完整的 TinyMCE 配置透传，可自定义插件、语言和工具栏</li>
              <li>与 AngularJS `ngModel` 双向绑定，内容实时同步</li>
              <li>支持禁用/只读状态、初始化回调、占位符以及多实例</li>
            </ul>
          </div>

          <div class="tinymce-demo-grid">
            <div class="tinymce-demo-item">
              <h3>1. 基本用法</h3>
              <p>默认配置，支持占位符和初始化回调，已包含演示链接与图片</p>
              <div class="tinymce-guide">
                <strong>操作指引：</strong>
                <ul>
                  <li>点击正文中的 <strong>TinyMCE 官网文档</strong> 链接，体验富文本里的锚点效果（可在预览中打开新窗口）。</li>
                  <li>双击示例图片触发大图预览，再尝试通过工具栏调整对齐、添加说明文字，观察实时渲染。</li>
                  <li>使用工具栏中的“链接/图片”按钮，添加更多资源以完成富文本说明。</li>
                </ul>
              </div>
              <ng-tinymce
                ng-model="tinymceModels.basic"
                placeholder="请输入正文..."
                image-preview-enabled="true"
                on-init="handleTinymceInit($editor, 'basic')"
              ></ng-tinymce>
              <div class="tinymce-status" ng-if="tinymceStatus.basic">
                {{ tinymceStatus.basic }}
              </div>
              <div class="demo-actions">
                <button class="btn btn-primary" ng-click="insertTinymceTemplate('basic')">
                  插入段落
                </button>
                <button class="btn btn-warning" ng-click="resetTinymceBasic()">
                  重置内容
                </button>
              </div>
              <div class="debug-output">
                <strong>绑定内容:</strong>
                <pre>{{ tinymceModels.basic }}</pre>
              </div>
            </div>

            <div class="tinymce-demo-item">
              <h3>2. 自定义工具栏 & 语言包</h3>
              <p>通过 <code>config</code> 传递 TinyMCE 官方配置，支持中文语言包</p>
              <ng-tinymce
                ng-model="tinymceModels.custom"
                config="tinymceCustomConfig"
                on-init="handleTinymceInit($editor, 'custom')"
              ></ng-tinymce>
              <div class="tinymce-status" ng-if="tinymceStatus.custom">
                {{ tinymceStatus.custom }}
              </div>
              <div class="demo-actions">
                <button class="btn btn-success" ng-click="insertTinymceTemplate('custom')">
                  追加模块
                </button>
              </div>
              <div class="debug-output">
                <strong>绑定内容:</strong>
                <pre>{{ tinymceModels.custom }}</pre>
              </div>
            </div>

            <div class="tinymce-demo-item">
              <h3>3. 表单集成与禁用</h3>
              <p>
                使用 <code>disabled</code> 切换只读状态，并配合
                <code>readonly-config</code> 启用预览 / 全屏等个性化功能；双击图片同样会弹出大图
              </p>
              <ng-tinymce
                ng-model="tinymceModels.readonly"
                config="tinymceMiniConfig"
                disabled="tinymceDisabled"
                readonly-config="tinymceReadonlyConfig"
                image-preview-enabled="true"
                on-init="handleTinymceInit($editor, 'readonly')"
              ></ng-tinymce>
              <div class="tinymce-status" ng-if="tinymceStatus.readonly">
                {{ tinymceStatus.readonly }}
              </div>
              <div class="demo-actions">
                <button class="btn btn-info" ng-click="toggleTinymceDisabled()">
                  {{ tinymceDisabled ? '切换为可编辑' : '切换为只读' }}
                </button>
                <button class="btn btn-primary" ng-click="insertTinymceTemplate('readonly')">
                  追加内容
                </button>
              </div>
              <div class="debug-output">
                <strong>绑定内容:</strong>
                <pre>{{ tinymceModels.readonly }}</pre>
              </div>
            </div>
          </div>
        </div>
      </div>

      <!-- KindEditor Demo -->
      <div class="tab-content" ng-class="{active: activeTab === 'kindeditor'}">
        <div class="demo-section">
          <h2>富文本编辑器 (KindEditor)</h2>

          <div class="feature-list">
            <strong>功能特性:</strong>
            <ul>
              <li>开源免费的 HTML 可视化编辑器，源码可自由修改</li>
              <li>支持图片、文件上传，支持多文件、批量上传</li>
              <li>支持浏览远程服务器图片、多文件管理</li>
              <li>内置代码高亮、表情、多媒体插入等实用功能</li>
              <li>支持标准化输出 HTML/XHTML 代码</li>
              <li>支持插件扩展，可自定义工具栏</li>
              <li>轻量级，加载速度快</li>
            </ul>
          </div>

          <div class="tree-demo-grid">
            <!-- Demo 1: 基本用法 -->
            <div class="tree-demo-item" style="grid-column: 1 / -1;">
              <h3>1. 基本用法</h3>
              <p>默认配置的富文本编辑器</p>
              <textarea id="editor1" style="width: 100%; height: 300px;">
&lt;p&gt;欢迎使用 KindEditor!&lt;/p&gt;
&lt;p&gt;这是一个功能强大的开源富文本编辑器。&lt;/p&gt;
              </textarea>
              <div class="demo-actions" style="margin-top: 15px;">
                <button class="btn btn-primary" ng-click="getEditorContent(1)">获取内容</button>
                <button class="btn btn-success" ng-click="setEditorContent(1)">设置内容</button>
                <button class="btn btn-warning" ng-click="clearEditorContent(1)">清空内容</button>
              </div>
              <div class="debug-output" ng-if="editorContent1">
                <strong>编辑器内容:</strong>
                <pre>{{ editorContent1 }}</pre>
              </div>
            </div>

            <!-- Demo 2: 简单工具栏 -->
            <div class="tree-demo-item" style="grid-column: 1 / -1;">
              <h3>2. 简单工具栏</h3>
              <p>只保留基本的文本编辑功能</p>
              <textarea id="editor2" style="width: 100%; height: 250px;">
&lt;p&gt;这是一个简化版的编辑器，只包含基本的文本格式化功能。&lt;/p&gt;
              </textarea>
              <div class="demo-actions" style="margin-top: 15px;">
                <button class="btn btn-primary" ng-click="getEditorContent(2)">获取内容</button>
              </div>
              <div class="debug-output" ng-if="editorContent2">
                <strong>编辑器内容:</strong>
                <pre>{{ editorContent2 }}</pre>
              </div>
            </div>

            <!-- Demo 3: 自定义尺寸 -->
            <div class="tree-demo-item" style="grid-column: 1 / -1;">
              <h3>3. 自定义尺寸</h3>
              <p>设置编辑器的宽度和高度</p>
              <textarea id="editor3" style="width: 100%; height: 200px;">
&lt;p&gt;这个编辑器有自定义的宽度和高度。&lt;/p&gt;
              </textarea>
              <div class="demo-actions" style="margin-top: 15px;">
                <button class="btn btn-primary" ng-click="getEditorContent(3)">获取内容</button>
              </div>
              <div class="debug-output" ng-if="editorContent3">
                <strong>编辑器内容:</strong>
                <pre>{{ editorContent3 }}</pre>
              </div>
            </div>

            <!-- Demo 4: 纯文本模式 -->
            <div class="tree-demo-item" style="grid-column: 1 / -1;">
              <h3>4. 纯文本模式</h3>
              <p>禁用所有 HTML 标签，只保留纯文本</p>
              <textarea id="editor4" style="width: 100%; height: 200px;">
这是纯文本模式，不会保留任何 HTML 标签。
              </textarea>
              <div class="demo-actions" style="margin-top: 15px;">
                <button class="btn btn-primary" ng-click="getEditorContent(4)">获取内容</button>
              </div>
              <div class="debug-output" ng-if="editorContent4">
                <strong>编辑器内容:</strong>
                <pre>{{ editorContent4 }}</pre>
              </div>
            </div>
          </div>

          <div class="code-block" style="margin-top: 30px;">
            <code>
// 基本用法<br>
var editor = KindEditor.create('#editor1', {<br>
&nbsp;&nbsp;width: '100%',<br>
&nbsp;&nbsp;height: '300px',<br>
&nbsp;&nbsp;resizeType: 1, // 0: 不能调整, 1: 高度可调整, 2: 宽高都可调整<br>
&nbsp;&nbsp;uploadJson: '/upload_json.php', // 图片上传接口<br>
&nbsp;&nbsp;fileManagerJson: '/file_manager_json.php', // 文件管理接口<br>
&nbsp;&nbsp;allowFileManager: true<br>
});<br>
<br>
// 简单工具栏<br>
var editor = KindEditor.create('#editor2', {<br>
&nbsp;&nbsp;items: [<br>
&nbsp;&nbsp;&nbsp;&nbsp;'fontname', 'fontsize', '|', 'forecolor', 'hilitecolor', 'bold',<br>
&nbsp;&nbsp;&nbsp;&nbsp;'italic', 'underline', 'removeformat', '|', 'justifyleft',<br>
&nbsp;&nbsp;&nbsp;&nbsp;'justifycenter', 'justifyright', 'insertorderedlist',<br>
&nbsp;&nbsp;&nbsp;&nbsp;'insertunorderedlist', '|', 'link', 'unlink'<br>
&nbsp;&nbsp;]<br>
});<br>
<br>
// 获取内容<br>
editor.html(); // 获取 HTML 内容<br>
editor.text(); // 获取纯文本内容<br>
<br>
// 设置内容<br>
editor.html('&lt;p&gt;新内容&lt;/p&gt;');<br>
<br>
// 清空内容<br>
editor.html('');
            </code>
          </div>
        </div>
      </div>
    </div>

    <script type="text/ng-template" id="strap/custom-modal.tpl.html">
      <div class="modal" tabindex="-1" role="dialog" aria-hidden="true">
        <div class="modal-dialog modal-md">
          <div class="modal-content">
            <div class="modal-header">
              <button type="button" class="close" aria-label="Close" ng-click="$hide()">
                <span aria-hidden="true">&times;</span>
              </button>
              <h4 class="modal-title">发布公告</h4>
            </div>
            <div class="modal-body">
              <p>可以在自定义模板内放置表单、列表或任何内容。</p>
              <ul class="list-unstyled">
                <li><span class="glyphicon glyphicon-send"></span> 支持调用 <code>$hide()</code> / <code>$dismiss()</code> 控制弹窗。</li>
                <li><span class="glyphicon glyphicon-time"></span> 结合 <code>backdrop="static"</code> 可阻止外部区域关闭。</li>
              </ul>
            </div>
            <div class="modal-footer">
              <button type="button" class="btn btn-default" ng-click="$hide()">稍后</button>
              <button type="button" class="btn btn-primary" ng-click="$hide()">立即发布</button>
            </div>
          </div>
        </div>
      </div>
    </script>

    <script src="https://cdn.jsdelivr.net/npm/angular@1.8.3/angular.min.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/angular-strap@2.3.12/dist/angular-strap.min.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/angular-strap@2.3.12/dist/angular-strap.tpl.min.js"></script>
    <script src="../dist/ng-components.js"></script>
    <script charset="utf-8" src="../lib/kindeditor/kindeditor-all.js"></script>
    <script charset="utf-8" src="../lib/kindeditor/lang/zh-CN.js"></script>
    <script>
      angular
        .module("demoApp", ["ngComponents"])
        .config(["$locationProvider", function ($locationProvider) {
          $locationProvider.hashPrefix("");
        }])
        .controller("DemoController", ["$scope", "$confirm", "$timeout", "$q", "ngToast", "$alert", "$location", "$window", "$document", "$loading", function ($scope, $confirm, $timeout, $q, ngToast, $alert, $location, $window, $document, $loading) {
          // 辅助函数：获取变量类型
          $scope.getType = function(value) {
            return typeof value;
          };

          // Tab控制
          $scope.activeTab = "confirm";
          $scope.setActiveTab = function (tab) {
            $scope.activeTab = tab;

            if (tab === "strap") {
              $timeout(function() {
                updateStrapActiveSection();
              }, 0);
            }
          };

          // Confirm Demo
          $scope.showInfo = function () {
            $confirm
              .show({
                title: "信息提示",
                content: "这是一个信息提示对话框",
                type: "info",
                okText: "知道了",
                cancelText: "取消"
              })
              .then(
                function () {
                  console.log("用户点击了确定");
                },
                function () {
                  console.log("用户点击了取消");
                }
              );
          };

          $scope.showSuccess = function () {
            $confirm
              .show({
                title: "操作成功",
                content: "您的操作已成功完成！",
                type: "success",
                okText: "太好了",
                cancelText: "关闭"
              })
              .then(
                function () {
                  console.log("用户点击了确定");
                },
                function () {
                  console.log("用户点击了取消");
                }
              );
          };

          $scope.showWarning = function () {
            $confirm
              .show({
                title: "警告",
                content: "此操作可能会有风险，请谨慎操作",
                type: "warning",
                okText: "继续",
                cancelText: "取消"
              })
              .then(
                function () {
                  console.log("用户选择继续");
                },
                function () {
                  console.log("用户选择取消");
                }
              );
          };

          $scope.showDanger = function () {
            $confirm
              .show({
                title: "危险操作",
                content: "此操作不可恢复，确定要删除吗？",
                type: "danger",
                okText: "确定删除",
                cancelText: "我再想想"
              })
              .then(
                function () {
                  console.log("用户确认删除");
                },
                function () {
                  console.log("用户取消删除");
                }
              );
          };

          $scope.showCustom = function () {
            $confirm
              .show({
                title: "自定义对话框",
                content:
                  '<p>支持 <strong>HTML</strong> 内容</p><ul><li>列表项1</li><li>列表项2</li></ul>',
                type: "info",
                okText: "接受",
                cancelText: "拒绝"
              })
              .then(
                function () {
                  console.log("用户点击接受");
                },
                function () {
                  console.log("用户点击拒绝");
                }
              );
          };

          // DatePicker Demo Data
          $scope.selectedDate = new Date();
          $scope.birthdayString = "1995/08/16";
          var now = new Date();
          $scope.rangeStart = new Date(now.getFullYear(), now.getMonth(), 1);
          $scope.rangeEnd = new Date(now.getFullYear(), now.getMonth() + 1, 0);
          $scope.projectStart = null;
          $scope.meetingDay = null;
          $scope.lockedDate = new Date(now.getFullYear(), now.getMonth(), 15);

          // Image Preview Demo Data
          $scope.imagePreviewDisabled = false;
          $scope.previewImages = [
            {
              title: "雪山星空",
              desc: "双击预览高清星空雪山摄影作品",
              thumb: "https://picsum.photos/id/1015/320/200",
              full: "https://picsum.photos/id/1015/1200/800"
            },
            {
              title: "森林瀑布",
              desc: "层叠水流与森林的细节表现",
              thumb: "https://picsum.photos/id/1018/320/200",
              full: "https://picsum.photos/id/1018/1200/800"
            },
            {
              title: "城市夜景",
              desc: "摩天楼与灯光交织的都市夜色",
              thumb: "https://picsum.photos/id/1011/320/200",
              full: "https://picsum.photos/id/1011/1200/800"
            }
          ];

          // Toast Demo
          $scope.toastHistory = [];

          function recordToast(type, message) {
            $scope.toastHistory.unshift({
              type: type,
              message: message,
              time: new Date().toLocaleTimeString()
            });

            if ($scope.toastHistory.length > 10) {
              $scope.toastHistory.pop();
            }
          }

          $scope.getToastCount = function() {
            return ngToast.toasts.length;
          };

          $scope.showToastSuccess = function() {
            var message = "数据保存成功";
            ngToast.success(message);
            recordToast('success', message);
          };

          $scope.showToastInfo = function() {
            var message = "系统将在凌晨 2 点进行维护";
            ngToast.info({
              title: "系统通知",
              message: message,
              duration: 5000
            });
            recordToast('info', message);
          };

          $scope.showToastWarning = function() {
            var message = "表单中仍有必填项未完成";
            ngToast.warning({
              title: "请注意",
              message: message,
              duration: 6000
            });
            recordToast('warning', message);
          };

          $scope.showToastDanger = function() {
            var message = "接口请求失败，请稍后重试";
            ngToast.danger({
              title: "操作失败",
              message: message,
              duration: 0 // 需要手动关闭
            });
            recordToast('danger', message);
          };

          $scope.showToastCustom = function() {
            var message = '<div>您已完成 <strong>90%</strong> 的配置。</div><div style="margin-top:6px;">剩余步骤：上传合同、填写发票信息。</div>';
            ngToast.show({
              title: "配置进度",
              message: message,
              type: "info",
              duration: 7000,
              customClass: "toast-progress"
            });
            recordToast('custom', '配置进度提醒');
          };

          $scope.stackToast = function() {
            ["用户A提交审批", "用户B提交审批", "用户C提交审批"].forEach(function(msg, index) {
              ngToast.show({
                title: "新审批请求",
                message: msg,
                type: "success",
                duration: 2500 + index * 300
              });
              recordToast('success', msg);
            });
          };

          $scope.clearToasts = function() {
            ngToast.clearAll();
            recordToast('clear', '已清空全部 Toast');
          };

          // Angular-Strap Demo Data
          $scope.strapDropdownItems = [
            { label: "新建任务" },
            { label: "发布公告" },
            { label: "导出报表" },
            { label: "归档" }
          ];

          $scope.strapDropdownSelected = "选择操作";
          $scope.selectDropdown = function(label) {
            $scope.strapDropdownSelected = label;
          };

          $scope.strapCheckboxes = {
            analytics: true,
            reports: false,
            notify: true
          };

          $scope.strapRadioValue = "monthly";

          $scope.strapCollapse = {
            active: 0,
            sections: [
              {
                title: "性能监控",
                content: "展示系统 CPU、内存、响应时间等实时性能指标。"
              },
              {
                title: "队列任务",
                content: "列出待处理任务，支持快速重试和取消操作。"
              },
              {
                title: "安全提醒",
                content: "聚合登录异常、风控报警等安全相关事件。"
              }
            ]
          };

          $scope.strapTabs = {
            active: 0,
            stats: {
              uptime: "132 小时",
              queue: 5,
              errors: 2
            }
          };

          $scope.strapSelect = {
            single: null,
            multiple: [],
            options: [
              { group: "华北", label: "北京", value: "beijing" },
              { group: "华北", label: "天津", value: "tianjin" },
              { group: "华东", label: "上海", value: "shanghai" },
              { group: "华东", label: "杭州", value: "hangzhou" },
              { group: "华南", label: "广州", value: "guangzhou" },
              { group: "华南", label: "深圳", value: "shenzhen" }
            ],
            tags: [
              { label: "紧急", value: "urgent" },
              { label: "待审核", value: "pending" },
              { label: "归档", value: "archived" }
            ]
          };

          $scope.strapDate = new Date();
          $scope.strapTime = new Date();

          $scope.strapTypeaheadStates = [
            "Alabama",
            "Alaska",
            "Arizona",
            "Arkansas",
            "California",
            "Colorado",
            "Florida",
            "Georgia",
            "Hawaii",
            "Idaho",
            "Illinois",
            "Indiana",
            "Kansas",
            "Kentucky",
            "Louisiana",
            "Maine",
            "Maryland",
            "Massachusetts",
            "Michigan",
            "Minnesota",
            "Mississippi",
            "Missouri",
            "Montana",
            "Nebraska",
            "Nevada",
            "New Hampshire",
            "New Jersey",
            "New Mexico",
            "New York",
            "North Carolina",
            "Ohio",
            "Oklahoma",
            "Oregon",
            "Pennsylvania",
            "Rhode Island",
            "South Carolina",
            "South Dakota",
            "Tennessee",
            "Texas",
            "Utah",
            "Vermont",
            "Virginia",
            "Washington",
            "West Virginia",
            "Wisconsin",
            "Wyoming"
          ];

          $scope.strapTypeaheadValue = "";

          $scope.strapNavItems = [
            { id: "strap-overview", label: "概览" },
            { id: "strap-alert", label: "Alert" },
            { id: "strap-aside", label: "Aside" },
            { id: "strap-modal", label: "Modal" },
            { id: "strap-dropdown", label: "Dropdown" },
            { id: "strap-popover", label: "Popover" },
            { id: "strap-tooltip", label: "Tooltip" },
            { id: "strap-button", label: "Button" },
            { id: "strap-collapse", label: "Collapse" },
            { id: "strap-tabs", label: "Tabs" },
            { id: "strap-select", label: "Select" },
            { id: "strap-datepicker", label: "Date/Time" },
            { id: "strap-typeahead", label: "Typeahead" },
            { id: "strap-navbar", label: "Navbar" },
            { id: "strap-affix", label: "Affix & Scrollspy" }
          ];

          var strapSectionIds = $scope.strapNavItems.map(function(item) {
            return item.id;
          });

          $scope.activeStrapSection = strapSectionIds[0];

          var strapHeaderOffset = 120;
          var strapHighlightOffset = strapHeaderOffset + 20;
          var strapScrollTicking = false;
          var strapWinEl = angular.element($window);

          $scope.scrollToStrapSection = function(section, $event) {
            if ($event) {
              $event.preventDefault();
            }

            if ($scope.activeTab !== "strap") {
              $scope.activeTab = "strap";
            }

            var docEl = $document[0].documentElement;
            var bodyEl = $document[0].body;
            var target = $document[0].getElementById(section);

            if (!target) {
              return;
            }

            var currentScroll = $window.pageYOffset || docEl.scrollTop || 0;
            var targetTop =
              target.getBoundingClientRect().top + currentScroll - strapHeaderOffset;

            if (targetTop < 0) {
              targetTop = 0;
            }

            if (typeof $window.scrollTo === "function") {
              try {
                $window.scrollTo({
                  top: targetTop,
                  behavior: "smooth"
                });
              } catch (err) {
                $window.scrollTo(0, targetTop);
              }
            } else {
              docEl.scrollTop = targetTop;
              if (bodyEl) {
                bodyEl.scrollTop = targetTop;
              }
            }

            $scope.activeStrapSection = section;
            $location.hash(section);

            $timeout(function() {
              updateStrapActiveSection();
            }, 350);
          };

          function updateStrapActiveSection() {
            if ($scope.activeTab !== "strap") {
              return;
            }

            var docEl = $document[0].documentElement;
            var scrollTop = ($window.pageYOffset || docEl.scrollTop || 0) + strapHighlightOffset;
            var current = strapSectionIds[0];

            strapSectionIds.forEach(function(id) {
              var el = $document[0].getElementById(id);

              if (!el) {
                return;
              }

              if (scrollTop >= el.offsetTop) {
                current = id;
              }
            });

            if (current !== $scope.activeStrapSection) {
              $scope.$applyAsync(function() {
                $scope.activeStrapSection = current;
              });
            }
          }

          function onStrapScroll() {
            if ($scope.activeTab !== "strap") {
              return;
            }

            if (strapScrollTicking) {
              return;
            }

            strapScrollTicking = true;

            if ($window.requestAnimationFrame) {
              $window.requestAnimationFrame(runStrapScrollUpdate);
            } else {
              $timeout(runStrapScrollUpdate, 120);
            }
          }

          function runStrapScrollUpdate() {
            strapScrollTicking = false;
            updateStrapActiveSection();
          }

          strapWinEl.on("scroll", onStrapScroll);

          $scope.$on("$destroy", function() {
            strapWinEl.off("scroll", onStrapScroll);
          });

          $timeout(updateStrapActiveSection, 0);

          var initialStrapHash = $location.hash();
          if (initialStrapHash && strapSectionIds.indexOf(initialStrapHash) !== -1) {
            $timeout(function() {
              $scope.activeTab = "strap";
              $scope.scrollToStrapSection(initialStrapHash);
            }, 100);
          }

          var strapAlertCopy = {
            success: {
              title: "操作成功",
              content: "数据已保存，可以继续下一步。"
            },
            info: {
              title: "提示信息",
              content: "这是一个普通的信息通知。"
            },
            warning: {
              title: "注意风险",
              content: "请确认输入信息是否正确。"
            },
            danger: {
              title: "操作失败",
              content: "服务器暂时不可用，请稍后重试。"
            }
          };

          $scope.openStrapAlert = function(type) {
            var payload = strapAlertCopy[type] || strapAlertCopy.info;
            $alert(
              angular.extend(
                {
                  placement: "top",
                  container: "body",
                  duration: 3,
                  show: true,
                  type: type
                },
                payload
              )
            );
          };

          function ensureRoute(path) {
            if (!path) {
              path = "/dashboard";
              $location.path(path);
            }
            $scope.strapCurrentRoute = path;
          }

          ensureRoute($location.path());

          $scope.setStrapRoute = function(path) {
            $location.path(path);
            $scope.strapCurrentRoute = path;
          };

          $scope.$watch(function() {
            return $location.path();
          }, function(newPath) {
            if (newPath) {
              $scope.strapCurrentRoute = newPath;
            }
          });

          // Select Demo Data
          $scope.cityOptions = [
            { id: "bj", label: "北京" },
            { id: "sh", label: "上海" },
            { id: "gz", label: "广州" },
            { id: "sz", label: "深圳" },
            { id: "hz", label: "杭州" },
            { id: "cd", label: "成都" },
            { id: "xa", label: "西安" },
            { id: "nj", label: "南京" }
          ];

          $scope.frameworkOptions = [
            { id: "angular", label: "Angular" },
            { id: "react", label: "React" },
            { id: "vue", label: "Vue" },
            { id: "svelte", label: "Svelte" },
            { id: "solid", label: "SolidJS" }
          ];

          var allCountries = [
            { code: "CN", name: "中国" },
            { code: "US", name: "美国" },
            { code: "JP", name: "日本" },
            { code: "DE", name: "德国" },
            { code: "FR", name: "法国" },
            { code: "GB", name: "英国" },
            { code: "CA", name: "加拿大" },
            { code: "AU", name: "澳大利亚" },
            { code: "BR", name: "巴西" },
            { code: "IN", name: "印度" },
            { code: "SG", name: "新加坡" },
            { code: "ZA", name: "南非" }
          ];

          $scope.remoteDefaultOptions = allCountries.slice(0, 8);

          $scope.remoteSearchCountries = function (params) {
            var keyword = params && params.keyword ? params.keyword.toLowerCase() : "";

            return $q(function (resolve) {
              $timeout(function () {
                var filtered = allCountries
                  .filter(function (item) {
                    if (!keyword) {
                      return true;
                    }

                    return (
                      item.name.toLowerCase().indexOf(keyword) !== -1 ||
                      item.code.toLowerCase().indexOf(keyword) !== -1
                    );
                  })
                  .slice(0, 12);

                resolve(filtered);
              }, 400);
            });
          };

          $scope.selectedCity = "sh";
          $scope.selectedSearchableCity = null;
          $scope.selectedFrameworks = ["angular", "vue"];
          $scope.selectedCountry = "CN";
          $scope.selectedCountryList = ["US", "JP"];
          $scope.selectedDisabledCity = "bj";

          // Tree Demo Data 1
          $scope.treeData1 = [
            {
              BpaId: "1",
              cnName: "一级节点1",
              children: [
                {
                  BpaId: "1-1",
                  cnName: "二级节点1-1",
                  children: [
                    {
                      BpaId: "1-1-1",
                      cnName: "三级节点1-1-1",
                      children: []
                    }
                  ]
                },
                {
                  BpaId: "1-2",
                  cnName: "二级节点1-2",
                  children: []
                }
              ]
            },
            {
              BpaId: "2",
              cnName: "一级节点2",
              children: [
                {
                  BpaId: "2-1",
                  cnName: "二级节点2-1",
                  children: []
                }
              ]
            }
          ];

          // Tree Demo Data 2 - Complex Organization
          $scope.treeData2 = [
            {
              BpaId: "D1",
              cnName: "董事会",
              children: [
                {
                  BpaId: "D1-1",
                  cnName: "战略委员会",
                  children: [
                    { BpaId: "D1-1-A", cnName: "战略规划组", children: [] },
                    { BpaId: "D1-1-B", cnName: "投资决策组", children: [] }
                  ]
                },
                {
                  BpaId: "D1-2",
                  cnName: "审计委员会",
                  children: [
                    { BpaId: "D1-2-A", cnName: "内部审计组", children: [] },
                    { BpaId: "D1-2-B", cnName: "风险控制组", children: [] }
                  ]
                }
              ]
            },
            {
              BpaId: "M1",
              cnName: "管理层",
              children: [
                {
                  BpaId: "M1-1",
                  cnName: "技术部",
                  children: [
                    {
                      BpaId: "M1-1-A",
                      cnName: "研发团队",
                      children: [
                        { BpaId: "M1-1-A-1", cnName: "前端组", children: [] },
                        { BpaId: "M1-1-A-2", cnName: "后端组", children: [] },
                        { BpaId: "M1-1-A-3", cnName: "测试组", children: [] }
                      ]
                    },
                    { BpaId: "M1-1-B", cnName: "运维团队", children: [] }
                  ]
                },
                {
                  BpaId: "M1-2",
                  cnName: "市场部",
                  children: [
                    { BpaId: "M1-2-A", cnName: "营销团队", children: [] },
                    { BpaId: "M1-2-B", cnName: "品牌团队", children: [] }
                  ]
                },
                {
                  BpaId: "M1-3",
                  cnName: "人力资源部",
                  children: [
                    { BpaId: "M1-3-A", cnName: "招聘组", children: [] },
                    { BpaId: "M1-3-B", cnName: "培训组", children: [] }
                  ]
                }
              ]
            },
            {
              BpaId: "T1",
              cnName: "技术支持",
              children: [
                { BpaId: "T1-1", cnName: "客服团队", children: [] },
                { BpaId: "T1-2", cnName: "技术支持团队", children: [] }
              ]
            }
          ];

          // Tree Demo Data 3 - Custom Fields
          $scope.treeData3 = [
            {
              id: "dept-1",
              name: "销售部门",
              children: [
                {
                  id: "dept-1-1",
                  name: "华东区",
                  children: [
                    { id: "dept-1-1-1", name: "上海", children: [] },
                    { id: "dept-1-1-2", name: "杭州", children: [] }
                  ]
                },
                {
                  id: "dept-1-2",
                  name: "华北区",
                  children: [
                    { id: "dept-1-2-1", name: "北京", children: [] },
                    { id: "dept-1-2-2", name: "天津", children: [] }
                  ]
                }
              ]
            },
            {
              id: "dept-2",
              name: "生产部门",
              children: [
                { id: "dept-2-1", name: "一车间", children: [] },
                { id: "dept-2-2", name: "二车间", children: [] }
              ]
            }
          ];

          // Tree Demo Data 4 - Large Tree (模拟大型组织架构)
          function generateLargeTree() {
            var largeTree = [];

            // 生成6个一级部门
            for (var i = 1; i <= 6; i++) {
              var dept = {
                BpaId: "DEPT-" + i,
                cnName: "集团第" + i + "事业部",
                children: []
              };

              // 每个一级部门下有5个二级部门
              for (var j = 1; j <= 5; j++) {
                var subDept = {
                  BpaId: "DEPT-" + i + "-" + j,
                  cnName: "第" + i + "事业部-" + ["研发中心", "市场中心", "运营中心", "财务中心", "人力中心"][j-1],
                  children: []
                };

                // 每个二级部门下有4个三级部门
                for (var k = 1; k <= 4; k++) {
                  var team = {
                    BpaId: "DEPT-" + i + "-" + j + "-" + k,
                    cnName: "团队" + k + "组",
                    children: []
                  };

                  // 每个三级部门下有6个员工
                  for (var m = 1; m <= 6; m++) {
                    team.children.push({
                      BpaId: "DEPT-" + i + "-" + j + "-" + k + "-" + m,
                      cnName: "员工" + m + " (" + ["张三", "李四", "王五", "赵六", "钱七", "孙八"][m-1] + ")",
                      children: []
                    });
                  }

                  subDept.children.push(team);
                }

                dept.children.push(subDept);
              }

              largeTree.push(dept);
            }

            return largeTree;
          }

          $scope.treeData4 = generateLargeTree();

          // 计算树的统计信息
          $scope.treeData4Stats = {
            level1: 6,
            level2: 5,
            level3: 4,
            level4: 6,
            totalNodes: 6 * (1 + 5 * (1 + 4 * (1 + 6)))
          };

          console.log("生成大型树数据:", $scope.treeData4.length, "个一级节点，总节点数:", $scope.treeData4Stats.totalNodes);

          // Initialize selected IDs for multi-level-tree
          $scope.selectedIds1_1 = [];
          $scope.selectedIds1_2 = [];
          $scope.selectedIds1_3 = [];
          $scope.selectedIds1_4 = [];
          $scope.selectedIds1_5 = ["D1", "M1", "T1"]; // 初始值示例
          $scope.selectedIds1_6 = [];
          $scope.selectedIds1_7 = []; // 大型树

          // Initialize selected IDs for tree-select
          $scope.selectIds1 = [];
          $scope.selectIds2 = [];
          $scope.selectIds3 = [];
          $scope.selectIds4 = [];
          $scope.selectIds5 = ["1", "2"]; // 禁用状态的初始值
          $scope.selectIds6 = ["M1-1"]; // 带初始值示例
          $scope.selectIds7 = []; // 隐藏搜索框示例
          $scope.selectIds8 = ["M1-1"]; // 综合测试: 选中产品部(包含所有子部门)

          // Radio Demo Data
          // 基本字符串数组
          $scope.radioOptions1 = ['选项A', '选项B', '选项C'];

          // 对象数组
          $scope.radioOptions2 = [
            { label: '苹果', value: 'apple' },
            { label: '香蕉', value: 'banana' },
            { label: '橙子', value: 'orange' }
          ];

          // 部分禁用的选项
          $scope.radioOptions3 = [
            { label: '可选项1', value: 'option1' },
            { label: '禁用项', value: 'option2', disabled: true },
            { label: '可选项2', value: 'option3' }
          ];

          // 数字选项
          $scope.radioOptions4 = [1, 2, 3, 4, 5];

          // 长列表
          $scope.radioOptions5 = [
            { label: '北京', value: 'beijing' },
            { label: '上海', value: 'shanghai' },
            { label: '广州', value: 'guangzhou' },
            { label: '深圳', value: 'shenzhen' },
            { label: '杭州', value: 'hangzhou' },
            { label: '成都', value: 'chengdu' },
            { label: '武汉', value: 'wuhan' }
          ];

          // 初始化选中值
          $scope.radioValue1 = '';
          $scope.radioValue2 = '';
          $scope.radioValue3 = '';
          $scope.radioValue4 = '选项A'; // 禁用状态的初始值
          $scope.radioValue5 = 'option1';
          $scope.radioValue6 = '选项B'; // 带初始值
          $scope.radioValue7 = 3; // 数字初始值
          $scope.radioValue8 = 'beijing';

          // Resize Demo Data
          $scope.resizeInfo1 = {};
          $scope.resizeInfo2 = {};
          $scope.resizeInfo3 = {};
          $scope.resizeInfo4 = {};
          $scope.resizeInfo5 = {};
          $scope.resizeInfo6 = {};
          $scope.resizeInfo7 = {};
          $scope.resizeInfo8 = {};

          $scope.updateResizeInfo2 = function(width, height) {
            $scope.resizeInfo2 = { width: width, height: height };
          };

          $scope.updateResizeInfo3 = function(width, height) {
            $scope.resizeInfo3 = { width: width, height: height };
          };

          $scope.updateResizeInfo4 = function(width, height) {
            $scope.resizeInfo4 = { width: width, height: height };
          };

          $scope.updateResizeInfo5 = function(width, height) {
            $scope.resizeInfo5 = { width: width, height: height };
          };

          $scope.updateResizeInfo6 = function(width, height) {
            $scope.resizeInfo6 = { width: width, height: height };
          };

          $scope.updateResizeInfo7 = function(width, height) {
            $scope.resizeInfo7 = { width: width, height: height };
          };

          $scope.updateResizeInfo8 = function(width, height) {
            $scope.resizeInfo8 = { width: width, height: height };
          };

          // Loading Demo
          // 全局加载演示
          $scope.showGlobalLoading = function() {
            $loading.show();
          };

          $scope.showGlobalLoadingWithText = function() {
            $loading.show({ text: '正在加载数据...' });
          };

          $scope.showGlobalLoadingCustom = function() {
            $loading.show({
              text: '处理中，请稍候...',
              color: '#9333ea',
              size: 'large'
            });
          };

          $scope.hideGlobalLoading = function() {
            $loading.hide();
          };

          // 局部加载演示
          $scope.loading1 = false;
          $scope.loading2 = false;
          $scope.loading3 = false;
          $scope.loading4 = false;
          $scope.loading5 = false;
          $scope.loading6 = false;
          $scope.asyncData6 = false;

          $scope.toggleLoading = function(index) {
            $scope['loading' + index] = !$scope['loading' + index];
          };

          $scope.simulateAsyncLoad = function(index) {
            $scope['loading' + index] = true;
            $scope['asyncData' + index] = false;

            $timeout(function() {
              $scope['loading' + index] = false;
              $scope['asyncData' + index] = true;
            }, 3000);
          };

          // TinyMCE Demo
          var tinymceLinkBlock =
            '<p>了解更多：<a href="https://www.tiny.cloud/docs/" target="_blank" rel="noopener noreferrer">TinyMCE 官网文档</a></p>';
          var tinymceImageBlock =
            '<p><img src="https://picsum.photos/seed/ng-components-tinymce/640/320" alt="TinyMCE 演示图片" style="max-width:100%;height:auto;border-radius:8px;display:block;margin:12px auto;" /></p>';

          var tinymceBasicTemplate =
            '<p><strong>欢迎使用 TinyMCE 富文本组件。</strong></p><p>这是一个默认段落，可以通过 ng-model 即时同步。</p>' +
            tinymceLinkBlock +
            tinymceImageBlock;
          var tinymceCustomTemplate =
            '<h3>版本更新日志</h3><ul><li>支持 <code>config</code> 自定义插件与工具栏</li><li>支持中文语言包和全屏预览</li><li>支持表格、媒体等富文本能力</li></ul>' +
            '<p>插入的富文本元素同样支持链接与图片，请编辑下方示例。</p>' +
            tinymceLinkBlock +
            tinymceImageBlock;
          var tinymceReadonlyTemplate =
            '<p>这是一段只读内容，用于展示禁用状态下的样式。</p><p>点击下方按钮可以追加内容或切换为可编辑。</p>' +
            tinymceLinkBlock +
            tinymceImageBlock;

          $scope.tinymceModels = {
            basic: tinymceBasicTemplate,
            custom: tinymceCustomTemplate,
            readonly: tinymceReadonlyTemplate
          };

          $scope.tinymceStatus = {};
          $scope.tinymceDisabled = false;

          $scope.tinymceCustomConfig = {
            height: 360,
            menubar: true,
            plugins: 'preview code lists link image table media fullscreen',
            toolbar:
              'undo redo | preview fullscreen | styles | bold italic underline forecolor backcolor | alignleft aligncenter alignright alignjustify | bullist numlist outdent indent | link image media table | code',
            language_url: 'https://cdn.jsdelivr.net/npm/tinymce-i18n/langs5/zh_CN.js',
            language: 'zh_CN'
          };

          $scope.tinymceMiniConfig = {
            height: 260,
            menubar: false,
            plugins: 'lists code',
            toolbar:
              'undo redo | bold italic underline | forecolor backcolor | bullist numlist | alignleft aligncenter alignright | removeformat code'
          };

          $scope.tinymceReadonlyConfig = {
            menubar: false,
            toolbar: 'preview fullscreen',
            plugins: 'fullscreen preview',
            toolbar_sticky: false
          };

          $scope.handleTinymceInit = function(editor, key) {
            $scope.$applyAsync(function() {
              $scope.tinymceStatus[key] = '编辑器 #' + editor.id + ' 已就绪';
            });
          };

          $scope.insertTinymceTemplate = function(target) {
            var snippet =
              '<p><strong>新内容:</strong> ' + new Date().toLocaleString() + '</p>';
            $scope.tinymceModels[target] = ($scope.tinymceModels[target] || '') + snippet;
          };

          $scope.resetTinymceBasic = function() {
            $scope.tinymceModels.basic = tinymceBasicTemplate;
          };

          $scope.toggleTinymceDisabled = function() {
            $scope.tinymceDisabled = !$scope.tinymceDisabled;
          };

          // KindEditor Demo
          $scope.editors = {};
          $scope.editorContent1 = '';
          $scope.editorContent2 = '';
          $scope.editorContent3 = '';
          $scope.editorContent4 = '';

          // 初始化 KindEditor
          $scope.$watch('activeTab', function(newVal) {
            if (newVal === 'kindeditor') {
              $timeout(function() {
                // 如果编辑器已经存在,先销毁
                if ($scope.editors[1]) {
                  $scope.editors[1].remove();
                }
                if ($scope.editors[2]) {
                  $scope.editors[2].remove();
                }
                if ($scope.editors[3]) {
                  $scope.editors[3].remove();
                }
                if ($scope.editors[4]) {
                  $scope.editors[4].remove();
                }

                // 编辑器 1: 基本用法
                $scope.editors[1] = KindEditor.create('#editor1', {
                  width: '100%',
                  height: '300px',
                  resizeType: 1,
                  items: [
                    'source', '|', 'undo', 'redo', '|', 'preview', 'print', 'template', 'code', 'cut', 'copy', 'paste',
                    'plainpaste', 'wordpaste', '|', 'justifyleft', 'justifycenter', 'justifyright',
                    'justifyfull', 'insertorderedlist', 'insertunorderedlist', 'indent', 'outdent', 'subscript',
                    'superscript', 'clearhtml', 'quickformat', 'selectall', '|', 'fullscreen', '/',
                    'formatblock', 'fontname', 'fontsize', '|', 'forecolor', 'hilitecolor', 'bold',
                    'italic', 'underline', 'strikethrough', 'lineheight', 'removeformat', '|', 'image', 'multiimage',
                    'flash', 'media', 'insertfile', 'table', 'hr', 'emoticons', 'baidumap', 'pagebreak',
                    'anchor', 'link', 'unlink', '|', 'about'
                  ],
                  langType: 'zh-CN'
                });

                // 编辑器 2: 简单工具栏
                $scope.editors[2] = KindEditor.create('#editor2', {
                  width: '100%',
                  height: '250px',
                  resizeType: 1,
                  items: [
                    'fontname', 'fontsize', '|', 'forecolor', 'hilitecolor', 'bold',
                    'italic', 'underline', 'removeformat', '|', 'justifyleft',
                    'justifycenter', 'justifyright', 'insertorderedlist',
                    'insertunorderedlist', '|', 'link', 'unlink'
                  ],
                  langType: 'zh-CN'
                });

                // 编辑器 3: 自定义尺寸
                $scope.editors[3] = KindEditor.create('#editor3', {
                  width: '100%',
                  height: '200px',
                  resizeType: 1,
                  items: [
                    'source', '|', 'preview', 'undo', 'redo', '|', 'formatblock', 'fontname', 'fontsize', '|',
                    'forecolor', 'hilitecolor', 'bold', 'italic', 'underline', '|',
                    'justifyleft', 'justifycenter', 'justifyright', '|',
                    'insertorderedlist', 'insertunorderedlist', '|', 'link', 'unlink', 'image'
                  ],
                  langType: 'zh-CN'
                });

                // 编辑器 4: 纯文本模式
                $scope.editors[4] = KindEditor.create('#editor4', {
                  width: '100%',
                  height: '200px',
                  resizeType: 1,
                  filterMode: false,
                  items: [],
                  langType: 'zh-CN'
                });
              }, 100);
            }
          });

          // 获取编辑器内容
          $scope.getEditorContent = function(id) {
            if ($scope.editors[id]) {
              var content = $scope.editors[id].html();
              $scope['editorContent' + id] = content;
            }
          };

          // 设置编辑器内容
          $scope.setEditorContent = function(id) {
            if ($scope.editors[id]) {
              var newContent = '<p><strong>这是新设置的内容!</strong></p><p>通过 JavaScript 动态设置。</p>';
              $scope.editors[id].html(newContent);
              $scope['editorContent' + id] = '';
            }
          };

          // 清空编辑器内容
          $scope.clearEditorContent = function(id) {
            if ($scope.editors[id]) {
              $scope.editors[id].html('');
              $scope['editorContent' + id] = '';
            }
          };

          console.log("DemoController initialized");
        }]);
    </script>
  </body>
</html>
